【问题标题】:Java 8 Stream operation based on lists基于列表的 Java 8 Stream 操作
【发布时间】:2019-06-24 13:31:44
【问题描述】:

我有两个列表。第一个是字符串列表 - A 列表,第二个包含新类列表,比如说 B 类。

B 类包含 String 字段,例如 example1、example2、example3、example4 等等。

我尝试过类似的方法,但我认为它适用于克隆集合,而不是将特定值更改为 null。

listOfB.stream().flatMap(p -> Stream.of(p.getExample1(),p.getExample2(), 
p.getExample3(), p.getExample4()))
            .forEach(i -> {
                if (listOfA.contains(i)) {
                    i = null
                }
            });

我想要实现的是流过 B 对象列表,获取所有示例字段(从 1 到 4),然后检查 A 列表是否包含至少一个示例字段值,如果是,则设置此特定示例字段为空。

【问题讨论】:

  • Lambda 参数与方法参数没有什么不同,因此更改它不会在 lambda 之外产生影响。您正在寻找的是.filter() 方法。
  • 将值设置为null 要达到什么目的?

标签: java java-8 java-stream


【解决方案1】:

要仅使用一个流执行此操作,您必须在 lambda 中通过一系列 if 检查。

public void stack() {
    List<String> aList = Arrays.asList("foo2", "baz4");

    B b1 = new B("foo1", "foo2", "foo3", "foo4");
    B b2 = new B("bar1", "bar2", "bar3", "bar4");
    B b3 = new B("baz1", "baz2", "baz3", "baz4");

    List<B> bList = Stream.of(b1, b2, b3).peek(b -> {
        if (aList.contains(b.getExample1())) {
            b.setExample1(null);
        }
        if (aList.contains(b.getExample2())) {
            b.setExample2(null);
        }
        if (aList.contains(b.getExample3())) {
            b.setExample3(null);
        }
        if (aList.contains(b.getExample4())) {
            b.setExample4(null);
        }
    }).collect(Collectors.toList());

    System.out.println(bList);
}

输出:

B [example1=foo1, example2=null, example3=foo3, example4=foo4],

B [example1=bar1, example2=bar2, example3=bar3, example4=bar4],

B [example1=baz1, example2=baz2, example3=baz3, example4=null]

【讨论】:

  • 这是我正在寻找的,但我试图在同一个流中做清理功能。
  • @snowflake 我删除了 cleanup() 方法以更清楚地表明它只是一个流
【解决方案2】:

更改 lambda 参数在 lambda 之外没有任何影响。你要找的方法是.filter()

.filter(i -> !listOfA.contains(i))

虽然用filter 替换forEach 不会有太大作用,因为filter 不是终端操作。注意它如何返回Stream&lt;T&gt;。如果您希望更改在listOfB 中生效,您需要将流收集到一个新列表中并重新分配。

List<String> list = stream.collect(Collectors.toList())

【讨论】:

  • 如果我正确理解您的概念,此代码始终返回 false。 ListOfA 包含字符串,但 ListOfB 包含具有字段 example1 到 example4 的 B 对象。我想将每个对象中所有示例字段的值与 ListOfA 中的字符串进行比较;)
【解决方案3】:

你可以这样做:使用集合代替列表

bList = bList.stream().map(b -> b.modify(aSet))
            .collect(Collectors.toList());

bList.replaceAll(b -> b.modify(aSet));

并在B类中定义一个方法:

public B modify(Set<String> set) {
    this.example1 = set.contains(this.example1) ? null : this.example1;
    this.example2 = set.contains(this.example2) ? null : this.example2;
    this.example3 = set.contains(this.example3) ? null : this.example3;
    this.example4 = set.contains(this.example4) ? null : this.example4;
    return this;
}

【讨论】:

    猜你喜欢
    • 2017-12-21
    • 2014-08-14
    • 2017-11-06
    • 2018-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    相关资源
    最近更新 更多