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

时间:2015-01-07 15:25:28

标签: java java-8

我有一个类似于以下内容的对象

class MyObject {

    String type;
    List<String> subTypes;

}

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

到目前为止我已经

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

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

一个例子是

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 } ] }

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

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

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

但是我想在每个子类型上添加一个额外的过滤器,并且只匹配“&#39; Z&#39;在场。

2 个答案:

答案 0 :(得分:12)

你可以这样做:

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

这将获取

的所有MyObject个对象
  • 符合有关type成员的条件。
  • 包含符合其他条件的嵌套List<String>中的对象,以<predicate>
  • 表示

答案 1 :(得分:9)

我看到了@kocko接受的答案,这既是一个很好的答案也是完全正确的。但是,您可以轻松地将过滤器链接起来。

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

这基本上是做同样的事情,但&&操作数被删除而转而使用另一个过滤器。链接适用于Java 8 Stream API:s和IMO,它更易于阅读和遵循代码。