[英]Getting only required objects from a list using Java 8 Streams
考虑具有属性attrib1
, attrib2
和List<Child>
子attrib1
的Parent
类及其相应的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
对象中获取所有子Parent
。 在这里,我想只获得符合给定条件的List<Child>
中的那些子对象。
如何删除List中不遵守该条件并获取新列表的所有子对象。
如果您想接收所有孩子,您需要的是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
列表本身。
我可以理解你应该为子列表添加额外的过滤器:
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();
}
})
我知道这个问题差不多有两年了,但希望这个答案可以帮助别人。
有一个名为com.coopstools.cachemonads的库。 它扩展了java stream(和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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.