java8 流 - 过滤映射和聚合

java8 stream - filter map and aggregate

假设我有一个房间列表

List<Room> rooms;

并且每个房间都有一个人员列表。

使用java8流我想迭代房间列表,获取所有人,在每个节点上执行一些方法(doSomething())并获取列表所有过滤的对象。

这是使用 java 8 的最佳实践吗?

List<Asset> pesonsList= new ArrayList<>();
for (Room room : rooms) 
     room.getPersonsList().stream()
                       .filter(person -> person.isTall())
                       .forEach(person -> {
                               doSomething(person);
                               pesonsList.add(person);
                       });

你最好这样做:

List<Person> persons = 
    rooms.stream()
         .flatMap(room -> room.getPersonsList().stream())
         .filter(Person::isTall)
         .peek(this::doSomething)
         .collect(Collectors.toList());

除了@JBNizet 的回答,我建议用 persons() 方法替换 Room class 中的 getPersonsList() 方法:而不是

List<Person> getPersonsList() {...}

创建此方法:

Stream<Person> persons() {...}

第一个好处是流操作会变得更短:

List<Person> persons = rooms.stream()
     .flatMap(Room::persons)
     .filter(Person::isTall)
     .peek(this::doSomething)
     .collect(Collectors.toList());

第二个优点是它可能更独立于实现,因此效率更高。假设您在内部将人员存储在 Set 或数组中。使用 getPersonsList() 方法时,您需要先将所有人员复制到新列表中。使用 persons() 方法时,您可以轻松地直接从内部数据结构创建流,无论它是什么。我相信,它是 Java 8 种方法 return 内部对象流而不是某些特定的数据结构,它是 List 或数组或其他什么。