使用Java8流从列表中仅获取所需对象

使用Java8流从列表中仅获取所需对象,java,arraylist,java-8,java-stream,Java,Arraylist,Java 8,Java Stream,考虑一个具有属性attrib1、attrib2和List子类及其相应的getter和setter的Parent类 Child是另一个具有五个属性的类attrib1-attrib5,以及相应的getter和setter 现在我创建了一个列表父项。然后我想筛选出一个具有以下条件的列表:-Child.Attrib1>10 因此,我使用Java8流创建了以下查询 parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c

考虑一个具有属性
attrib1
attrib2
List
子类及其相应的getter和setter的
Parent

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

现在我创建了一个
列表
父项。然后我想筛选出一个具有以下条件的
列表:-
Child.Attrib1>10

因此,我使用Java8流创建了以下查询

parent.stream().filter(e -> e.getChild().stream().anyMatch(c -> c.getAttrib1() > 10));
但问题是我将获取每个
父对象中的所有子对象。在这里,我只想得到
列表中符合给定条件的子对象


如何删除列表中所有不符合条件的子对象并获取新列表

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

 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())))
如果尚未设置子项:

  • 您可以从列表中删除项目
  • 创建全新的父对象
要删除,可以使用迭代器:

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();
    }
})
parent.stream().filter(e->e.getChild().stream().anyMatch(c->c.getAttrib1>10))
.forEach(e->{
for(Iterator it=e.getChild().Iterator();it.hasNext();){
Child cur=it.next();

if(cur.getAttrib1()如果要接收所有子项,则需要一个
流。下面的表达式可能会起作用:

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

这将返回get属性值大于10的列表中所有父级的所有子级

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

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


这不会创建一个新的列表。相反,它会更新父母列表本身。

我知道这个问题已经问了将近2年了,但希望这个答案能帮助一些人

有一个名为com.cooptools.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());
List goodParents=CacheStream.of(父项)
.cache()
.map(父::getChildren)
.flatMap(集合::流)
.map(子::getAttrib1)
.过滤器(附件->附件>10)
.load()
.distinct()
.collect(Collectors.toList());
其中,父对象是数组或流

为了清楚起见,cache方法是存储父对象的方法,load方法是将父对象拉出的方法。如果父对象没有子对象,则在第一个映射之后需要一个筛选器来删除空列表

此库可用于任何需要对子对象执行操作的情况,包括映射/排序/筛选/等,但仍需要旧实体的情况

代码可以在(我在自述文件中包含了您的示例)中找到,也可以从maven下载:

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

com.cooptools
缓存单体
0.2.0

(或者,gradle,com.cooptools:cachemonads:0.2.0)

@sibnick:如果没有setChild,有任何方法可以实现这一点。这对我来说就像魅力一样有效。谢谢!通过flatmap,我将如何获得列表的筛选列表,因为我知道您的要求是在父列表中找到所有子列表,其中
getAttrib1()>10
列表
在哪里出现?flatMap正在将父对象中的所有子流合并到单个子流中。我的要求是删除列表中所有不符合条件的子对象并获得新列表。完全不同的问题是:(.更新答案。
parents.removeIf
从列表中删除
父对象
对象(而不是从
子对象
列表中匹配的子对象)。这是您想要的吗?