使用 Java 8 个流从列表中仅获取需要的 objects

Getting only required objects from a list using Java 8 Streams

考虑具有属性 attrib1attrib2List<Child> child 及其相应的 getter 和 setter 的 Parent class。

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

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

所以我通过 Java 8 个流创建了以下查询。

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

但问题是我会在每个 Parent object 中得到所有 child。这里我只想得到 List<Child> 中满足给定条件的 child object

如何把List中不符合条件的child object全部去掉,得到新的List。

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

 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())))

如果没有设置Child:

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

要删除你可以使用迭代器:

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();
    }
})

如果你想得到所有 children,你需要一个 Stream<Child>。以下表达式可能会起作用:

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

这应该return all children of all parents in the list where the get attribute value are greater than 10.

如果您想通过删除所有未满足条件的 child 元素来更新 parents 列表,您可以执行以下操作:

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

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

我知道这个问题已经有将近 2 年的历史了,但希望这个答案能对某人有所帮助。

有一个图书馆叫做 com.coopstools.cachemonads。它扩展了 java 流(和可选)类 以允许缓存实体供以后使用。

可以通过以下方式找到解决方案:

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());

其中,parents 是数组或流。

为清楚起见,缓存方法是存储 parent 的方法;而 load 方法是将 parent 拉回的方法。如果 parent 没有 children,则在第一个映射之后需要一个过滤器来删除空列表。

此库可用于需要对 children 执行操作的任何情况,包括 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)