如何在 List 的每个元素上调用方法?

2022-08-31 19:45:06

假设我有一个汽车列表:

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<Car> cars = //...
List<String> names = new ArrayList<String>();


for (Car c : cars ) {
    names.add(c.getName());
}

如何缩短上面的代码?简而言之,如何在List的每个元素上调用方法?

例如,在Python中:

[car.name for car in cars]

答案 1

Java 8将(希望)具有某种形式的lambda表达式,这将使这样的代码更加可行。(是否会有类似列表理解的东西是另一回事。

您的愿望已实现!

---编辑---
笑,好像在提示:forEach()

一定要看看这个。

特别是对于您的问题,它变成了以下几点:

// Suppose that I have already init the list of car
List<Car> cars = //...
List<String> names = new ArrayList<String>();

// LAMBDA EXPRESSION
cars.forEach( (car) -> names.add(car.getName()) );

他们在这里所做的一切真是太不可思议了。我很高兴看到将来使用它。

---EDIT---
我应该早点看到这个,但我无法抗拒,只能发布它。

jdk8 中添加的流功能允许使用映射方法

// Suppose that I have already init the list of car
List<Car> cars = //...

// LAMBDA EXPRESSION
List<String> names = cars.stream().map( car -> car.getName() ).collect( Collectors.toList() );

更简洁的是使用Java 8的方法参考oracle doc)。

List<String> names = cars.stream().map( Car::getName ).collect( Collectors.toList() );

答案 2

更新:

请参阅 aaiezza 对使用 lambda 表达式的 Java 8 解决方案的回答

Java 8之前的原始答案:

使用番石榴可以达到效果,实现已经比您拥有的更详细:Function

List<Car> cars = //...

Function<Car, String> carsToNames = new Function<Car, String>() {
   @Override
   public String apply(Car car) {
      return car.getName();
   }
}

List<String> names = Lists.transform(cars, carsToNames);

(请记住,Lists.transform 返回一个视图,该视图将懒惰地应用该函数 - 如果需要立即复制,则需要将返回的列表复制到新列表中。

因此,这并不能帮助您缩短代码,但这是一个示例,说明在Java中实现所需效果是多么冗长。

编辑:你可能会看看lambdaj,一个似乎接近你正在寻找的东西的库。我自己还没有尝试过,但主页显示了这个例子:

List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma"));
forEach(personInFamily).setLastName("Fusco");