简体   繁体   English

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

[英]Getting only required objects from a list using Java 8 Streams

Consider a Parent class with the attributes attrib1 , attrib2 and List<Child> child with its corresponding getters and setters. 考虑具有属性attrib1attrib2List<Child>attrib1Parent类及其相应的getter和setter。

The Child is another class with five attributes attrib1 - attrib5 with its corresponding getters and setters. Child是另一个具有五个属性attrib1类 - attrib5及其相应的getter和setter。

Now I created a List<Parent> parent. 现在我创建了一个List<Parent>父级。 Then I want to filter out a List<Parent> with following condition:- Child.Attrib1 > 10 ; 然后我想过滤掉具有以下条件的List<Parent> : - Child.Attrib1 > 10 ;

So I created the following query by Java 8 streams. 所以我用Java 8流创建了以下查询。

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

But the problem is I will get all the child in each Parent object. 但问题是我会在每个Parent对象中获取所有子Parent Here I want to get only those child object in List<Child> that obeys the given condition. 在这里,我想只获得符合给定条件的List<Child>中的那些子对象。

How should I remove all the child objects in List that doesn't obeys the condition and get the new List. 如何删除List中不遵守该条件并获取新列表的所有子对象。

What you need is a Stream<Child> if you want to receive all children. 如果您想接收所有孩子,您需要的是Stream<Child> The following expression might do the trick: 以下表达式可能会起到作用:

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

This should return all children of all parents in the list where the get attribute value is greater than 10. 这应该返回get属性值大于10的列表中所有父项的所有子项。

If you want to update the parents list by removing all child elements that fail a condition, you can do the following: 如果要通过删除条件失败的所有子元素来更新父列表,可以执行以下操作:

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

This doesn't create a new list. 这不会创建新列表。 Instead it updates the parents list itself. 相反,它会更新parents列表本身。

As I can understand you should add additional filter for child lists: 我可以理解你应该为子列表添加额外的过滤器:

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

If you have not setChild: 如果你还没有setChild:

  • You can remove items from lists 您可以从列表中删除项目
  • Create completly new parent objects 创建完全新的父对象

To remove you can use iterator: 要删除你可以使用迭代器:

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

I know the question is almost 2 years old, but hopefully this answer can help someone. 我知道这个问题差不多有两年了,但希望这个答案可以帮助别人。

There's a library called com.coopstools.cachemonads. 有一个名为com.coopstools.cachemonads的库。 It extends the java stream (and Optional) classes to allow caching of entities for later use. 它扩展了java stream(和Optional)类,允许实体的缓存供以后使用。

The solution can be found with: 解决方案可以找到:

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

where, parents is an array or stream. 其中,parent是一个数组或流。

For clarity, the cache method is what stores the parents; 为清楚起见,缓存方法是存储父母的方法; and the load method is what pulls the parents back out. 并且加载方法是让父母退出的原因。 And If a parent does not have children, a filter will be needed after the first map to remove the null lists. 如果父级没有子级,则在第一个映射之后将需要一个过滤器来删除空列表。

This library can be used in any situation where operations need to be performed on children, including map/sort/filter/etc, but where an older entity is still needed. 此库可用于需要对子项执行操作的任何情况,包括map / sort / filter / etc,但仍需要较旧的实体。

The code can be found at https://github.com/coopstools/cachemonads (where I've included your example in the readme), or can be downloaded from maven: 代码可以在https://github.com/coopstools/cachemonads找到(我在自述文件中包含了你的例子),或者可以从maven下载:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM