使用 Java 8 个流从列表中仅获取需要的 objects
Getting only required objects from a list using Java 8 Streams
考虑具有属性 attrib1
、attrib2
和 List<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)
考虑具有属性 attrib1
、attrib2
和 List<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)