使用Java 8 Streams从列表中仅获取所需对象

时间:2015-08-21 04:32:19

标签: java arraylist java-8 java-stream

考虑一个Parent类,其中包含属性attrib1attrib2List<Child>子项及其相应的getter和setter。

Child是另一个有五个属性attrib1 - attrib5及其相应的getter和setter的类。

现在我创建了一个List<Parent>父级。然后我想过滤掉List<Parent>以下条件: - Child.Attrib1 > 10;

所以我用Java 8流创建了以下查询。

parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1() > 10));

但问题是我会在每个Parent对象中获得所有孩子。在这里,我想只获得符合给定条件的List<Child>中的那些子对象。

如何删除List中不遵守该条件并获取新列表的所有子对象。

3 个答案:

答案 0 :(得分:6)

如果您想接收所有孩子,您需要的是Stream<Child>。以下表达式可能会起到作用:

parents.stream().flatMap(e -> e.getChildren().stream()).filter(c -> c.getAttrib1() > 10)

这应该返回get属性值大于10的列表中所有父项的所有子项。

如果要通过删除条件失败的所有子元素来更新父元素列表,可以执行以下操作:

parents.forEach(p -> p.getChildren().removeIf(c -> c.getAttrib1() > 10));

这不会创建新列表。相反,它会更新parents列表本身。

答案 1 :(得分:1)

据我所知,您应该为子列表添加额外的过滤器:

 parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1() > 10)).forEach(e -> e.setChild(e.getChild().stream().filter(c -> c.getAttrib1 > 10).collect(toList())))

如果你还没有setChild:

  • 您可以从列表中删除项目
  • 创建完整的新父对象

要删除,您可以使用迭代器:

parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1 > 10))
   .forEach(e -> {
      for(Iterator<Child> it = e.getChild().iterator(); it.hasNext();){
          Child cur = it.next();
          if(cur.getAttrib1() <= 10) it.remove();
    }
})

答案 2 :(得分:0)

我知道这个问题差不多有两年了,但希望这个答案可以帮助别人。

有一个名为com.coopstools.cachemonads的库。它扩展了java流(和Optional)类,允许实体的缓存供以后使用。

解决方案可以在以下位置找到:

List<Parent> goodParents = CacheStream.of(parents)
            .cache()
            .map(Parent::getChildren)
            .flatMap(Collection::stream)
            .map(Child::getAttrib1)
            .filter(att -> att > 10)
            .load()
            .distinct()
            .collect(Collectors.toList());

其中,parent是数组或流。

为清楚起见,缓存方法是存储父母的方法;并且加载方法是让父母退出的原因。如果父级没有子级,则在第一个映射之后将需要一个过滤器来删除空列表。

此库可用于需要对子项执行操作的任何情况,包括map / sort / filter / etc,但仍需要较旧的实体。

代码可以在https://github.com/coopstools/cachemonads找到(我在自述文件中包含了您的示例),或者可以从maven下载:

<dependency>
    <groupId>com.coopstools</groupId>
    <artifactId>cachemonads</artifactId>
    <version>0.2.0</version>
</dependency>

(或,gradle,com.coopstools:cachemonads:0.2.0)