java 列表中列表的Java 8 Stream过滤值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27822703/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 12:27:01  来源:igfitidea点击:

Java 8 Stream filtering value of list in a list

javajava-8

提问by Simon Kent

I have a an object which looks like the following

我有一个如下所示的对象

class MyObject {

    String type;
    List<String> subTypes;

}

Is it possible, given a list of MyObject's to use Java 8 streams to filter on both the type and then the subtype?

给定 MyObject 的列表,是否有可能使用 Java 8 流来过滤类型和子类型?

So far I have

到目前为止我有

myObjects.stream()
    .filter(t -> t.getType().equals(someotherType)
    .collect(Collections.toList());

but within this I also want another filter on eachof the subTypes filtering those on a particular subtype too. I can't figure out how to do this.

但在此我还希望每个子类型上的另一个过滤器也过滤特定子类型上的过滤器。我无法弄清楚如何做到这一点。

An example would be

一个例子是

myObject { type: A, subTypes [ { X, Y, Z } ] }
myObject { type: B, subTypes [ { W, X, Y } ] }
myObject { type: B, subTypes [ { W, X, Z } ] }
myObject { type: C, subTypes [ { W, X, Z } ] }

I would pass in matchType B and subType Z, so I would expect one result -> myObject type B, subtypes: W, X, Z

我会传入 matchType B 和 subType Z,所以我希望得到一个结果 -> myObject 类型 B,子类型:W、X、Z

the following currently returns 2 items in a list.

以下当前返回列表中的 2 个项目。

myObjects.stream()
    .filter(t -> t.getType().equals("B")
    .collect(Collectors.toList());

but I would like to add an additional filter over the each of the subtypes and only matching where 'Z' is present.

但我想在每个子类型上添加一个额外的过滤器,并且只匹配存在 'Z' 的地方。

回答by Konstantin Yovkov

You can do:

你可以做:

myObjects.stream()
         .filter(t -> t.getType().equals(someotherType) && 
                      t.getSubTypes().stream().anyMatch(<predicate>))
         .collect(Collectors.toList());

This will fetch all the MyObjectobjects which

这将获取所有MyObject对象

  • meet a criteria regarding the typemember.
  • contain objects in the nested List<String>that meet some other criteria, represented with <predicate>
  • 符合有关type会员的标准。
  • 包含嵌套List<String>中满足某些其他条件的对象,用<predicate>

回答by wassgren

I saw the accepted answer from @kocko which is both a good answer and totally correct. However there is a slightly alternative approach where you simply chain the filters.

我看到了@kocko 的公认答案,这既是一个很好的答案,又是完全正确的。但是,有一种稍微替代的方法,您只需将过滤器链接起来即可。

final List<MyObject> withBZ = myObjects.stream()
        .filter(myObj -> myObj.getType().equals("B"))
        .filter(myObj -> myObj.getSubTypes().stream().anyMatch("Z"::equals))
        .collect(Collectors.toList());

This is basically doing the same thing but the &&operand is removed in favour of another filter. Chaining works really well for the Java 8 Stream API:s and IMO it is easier to read and follow the code.

这基本上是在做同样的事情,但&&操作数被删除以支持另一个过滤器。链接对于 Java 8 Stream API:s 和 IMO 非常有效,它更容易阅读和遵循代码。