如何在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());