使用Java 8 Lambda或Stream API过滤列表

3

我的课程结构 -

class A {
    List<B> bList;
}

class B {
   List<C> cList;
}

现在我有一个A类列表,我想根据c.size() > 0的条件对其进行过滤。我可以使用两个for循环(一个用于列表A,另一个用于列表B)来过滤它,但我想知道是否可以使用Java Stream API过滤A列表而不使用for循环。

我的当前代码(已更新)-

List<A> result = = new ArrayList<>();
for (A a : aList) {
   List<B> tempBList = = new ArrayList<>();
   for (B b : a.getBList) {
       if (b.getCList.size() > 0) {
          tempBList.add(b);
       }
   }

   if (tempBList.size() > 0) {
       a.setBList(tempBList);
       result.add(a);
   }
}

你可能忘记在例子中 result.add(a); 语句后加上 break; - Lino
@RavindraRanwala 目前对于每个满足条件 b.c.size() > 0b 实例,他都添加了一个 a 实例。这看起来像是一个笔误。 - Lino
@RavindraRanwala 我想我们是彼此相邻的。a.b 是一个 List。OP 遍历该列表,然后检查项 b 是否有一个大于 0 的列表 b.c。如果是,则将 a 添加到结果中。当前代码对每个 b 都执行此操作。这意味着可能会有多个相同的 a 实例在结果列表中。 - Lino
@lino 有道理。在这种情况下需要使用 break。 - Ravindra Ranwala
@RavindraRanwala 那就是我想说的 ;) - Lino
显示剩余2条评论
2个回答

10

可以的:

List<A> result =
    listOfA.stream()
           .filter(a -> a.b.stream().anyMatch(b -> b.c.size() > 0))
           .collect(Collectors.toList());

假设您希望将通过过滤器的每个 A 实例添加到输出 List 一次。


1
尝试这个。items是您想要过滤的列表。
    List<A> result = new ArrayList<>();

    result = items.stream().filter(a -> a.b.stream().filter(b -> b.c.size() > 0).count() > 0).collect(Collectors.toList());

使用count()的想法很有趣。但请记住,filter(..).count(..) > 0将遍历整个A流。使用anyMatch()将产生相同的结果,但一旦找到一个已经有CA,它就会停止,这使得它更有效率。 - Malte Hartwig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接