【问题标题】:How can I call a method on each element of a List?如何在 List 的每个元素上调用方法?
【发布时间】:2011-11-05 12:22:36
【问题描述】:

假设我有一个汽车清单:

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]

【问题讨论】:

    标签: java list list-comprehension


    【解决方案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()) );
    

    他们在这里所做的真是令人难以置信。我很高兴看到它在未来被使用。

    ---编辑---
    我应该早点看到这个,但我忍不住发了贴。

    jdk8 中添加的 Stream 功能允许map method

    // 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 的 method references (oracle doc)。

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

    【讨论】:

      【解决方案2】:

      更新:

      有关使用 lambda 表达式的 Java 8 解决方案,请参阅 aaiezza 的 answer

      Java 8 之前的原始答案:

      使用 Guava 可以达到效果,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");
      

      【讨论】:

        【解决方案3】:

        除了去掉大括号和/或将所有代码移到一行之外,这可能不是一个好主意,你不能。

        【讨论】:

          【解决方案4】:

          在 common-lisp 中有一个 mapcar-function(这与上面的 car-example 无关)。 Java中的通用mapcar函数:

          static <LIST_TYPE, ELEM_TYPE> List<LIST_TYPE> mapcar(Collection<ELEM_TYPE> list, Function<ELEM_TYPE, LIST_TYPE> function)
          {
              return list.stream().map(function).collect(Collectors.toList());
          }
          

          以汽车为例:

          List<String> carNames = mapcar(cars, car -> car.getName());
          

          【讨论】:

            【解决方案5】:

            最好远离 Guava 的 Lists.transform,除非你知道它在做什么。看看这个 sn-p:

            public class User {
                private Integer id;
                // constructor, getters & setters
            }
            
            public class UserDto {
                private Integer id;
                private boolean processed;
            
                public UserDto(User user) {
                    this.id = user.getId();
                    this.processed = false;
                }
               // getters & setters
            }
            
            // now let's do actual transformation ...
            private List<UserDto> getUsers() {
                List<User> users = List.of(new User(1), new User(2));
                List<UserDto> userDtos = Lists.transform(users, UserDto::new);
                userDtos.forEach(userDto -> userDto.setProcessed(true));
                return userDtos;
            }
            

            您可能希望所有 DTO 的 processed 标志都设置为 true,但这不会发生。 虽然这是他们的“惰性视图”方法的结果,但仍然相当令人惊讶。

            【讨论】:

              【解决方案6】:

              如果您遇到困难并且仍然必须使用 Apache Commons,那么 Transformer 类可以提供帮助:http://apachecommonstipsandtricks.blogspot.de/2009/01/examples-of-functors-transformers.html

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2011-05-14
                • 1970-01-01
                • 2017-11-03
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多