如何在List的每个元素上调用方法?
假设我有一个汽车列表:
public class Car { private String brand; private String name; private String color; public Car() { // ... } public getName() { return name; } // ... }
// Suppose that I have already init the list of car List cars = //... List names = new ArrayList(); for (Car c : cars ) { names.add(c.getName()); }
如何缩短上面的代码? 简而言之,如何在List的每个元素上调用方法?
例如,在Python中:
[car.name for car in cars]
更新:
请参阅aaiezza对使用lambda表达式的Java 8解决方案的回答 。
原始的Java前8答案:
使用Guava可以实现这种效果, Function
实现已经比你拥有的更加冗长:
List cars = //... Function carsToNames = new Function() { @Override public String apply(Car car) { return car.getName(); } } List names = Lists.transform(cars, carsToNames);
(请记住, Lists.transform
返回一个视图,该视图将懒惰地应用该函数 – 如果您想要立即复制,则需要将返回的列表复制到新列表中。)
所以这并没有帮助你缩短你的代码,但它是一个例子,说明在Java中实现你想要的影响是多么冗长。
编辑:你可能会看看lambdaj ,一个似乎接近你正在寻找的库。 我自己没试过,但主页显示了这个例子:
List personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma")); forEach(personInFamily).setLastName("Fusco");
Java 8(希望)将具有某种forms的lambda表达式,这将使这样的代码更加可行。 (是否有类似列表推导的东西是另一回事。)
你的愿望已被授予!
– -编辑 – –
大声笑,好像在提示: forEach()
绝对检查一下。
特别是对于你的问题,它变成了以下内容:
// Suppose that I have already init the list of car List cars = //... List names = new ArrayList (); // LAMBDA EXPRESSION cars.forEach( (car) -> names.add(car.getName()) );
他们在这里所做的真的很令人难以置信。 我很高兴看到将来使用它。
– -编辑 – –
我应该早点看到这个,但我无法抗拒,只能发布它。
jdk8中添加的Streamfunction允许使用map方法 。
// Suppose that I have already init the list of car List cars = //... // LAMBDA EXPRESSION List names = cars.stream().map( car -> car.getName() ).collect( Collectors.toList() );
除了摆脱括号和/或将所有代码移动到一行,这可能不是一个好主意,你不能。
如果您遇到困难并且仍然必须使用Apache Commons,那么Transformer类可以提供帮助: http : //apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html
在common-lisp中有一个mapcar函数(这与上面的汽车示例无关)。 Java中的通用mapcar函数:
static List mapcar(Collection list, Function function) { return list.stream().map(function).collect(Collectors.toList()); }
对于汽车示例:
List carNames = mapcar(cars, car -> car.getName());