【问题标题】:Java 8 Stream filtering value of list in a listJava 8 Stream过滤列表中列表的值
【发布时间】:2015-01-07 15:25:27
【问题描述】:

我有一个如下所示的对象

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”的位置。

【问题讨论】:

  • 你能举一个比赛和错过的例子吗? subTypes 中的所有元素必须匹配吗?
  • 你想过滤subTypes还是什么?
  • “每个子类型上的另一个过滤器过滤特定子类型上的那些”到底是什么意思?请举个例子。

标签: java java-8


【解决方案1】:

你可以这样做:

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

这将获取所有MyObject 对象

  • 满足type 成员的标准。
  • 在嵌套的List&lt;String&gt; 中包含满足某些其他条件的对象,用&lt;predicate&gt; 表示

【讨论】:

  • 任何匹配都可以:3
【解决方案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());

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

【讨论】:

  • 我同意最后一句话。谢谢
  • 有什么理由使用 .stream().anyMatch("Z"::equals) 而不仅仅是 .contains("Z")?不确定我是否遗漏了什么,或者它们实际上是否相同。
【解决方案3】:

我在这个网站上找到了一堆例子:https://zetcode.com/java/streamfilter/

引用Java Stream多重过滤操作的例子

可以对一个流应用多个过滤器操作。

package com.zetcode;

import java.util.Arrays;
import java.util.function.IntConsumer;

public class JavaStreamMultipleFilters {

public static void main(String[] args) {

    int[] inums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
    
    IntConsumer icons = i -> System.out.print(i + " ");
    
    Arrays.stream(inums).filter(e -> e < 6 || e > 10)
            .filter(e -> e % 2 == 0).forEach(icons);
}

}

在示例中,我们对整数流应用多个过滤操作。

int[] inums = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };

我们有一个整数值数组。

IntConsumer icons = i -> System.out.print(i + " ");

IntConsumer 是一个接受单个整数值参数并且不返回结果的操作。

Arrays.stream(inums).filter(e -> e < 6 || e > 10)
        .filter(e -> e % 2 == 0).forEach(icons);

使用 Arrays.stream 方法从数组创建流。执行多个过滤操作。

2 4 12 14

这些整数满足所有过滤条件。

【讨论】:

    猜你喜欢
    • 2021-03-16
    • 1970-01-01
    • 2017-06-21
    • 2021-07-25
    • 2021-11-06
    • 1970-01-01
    • 2019-08-11
    • 2015-07-12
    • 2021-07-01
    相关资源
    最近更新 更多