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

2022-09-04 06:20:10

我有一个对象,如下所示

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,所以我期望得到一个结果 -> myObject 类型 B,子类型:W、X、Z

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

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

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


答案 1

您可以执行以下操作:

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

这将获取所有对象MyObject

  • 符合有关成员的标准。type
  • 包含嵌套中满足某些其他条件的对象,表示为List<String><predicate>

答案 2

我从@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来说非常有效,更容易阅读和遵循代码。&&


推荐