【问题标题】:Process,map and collect object in one stream call在一次流调用中处理、映射和收集对象
【发布时间】:2020-12-16 12:20:23
【问题描述】:

我有一个对象列表,我想先处理每个对象,然后将它们映射到另一个对象 对象,然后将它们收集到一个列表中。像这样:

list.stream().forEach(doSomething).map(mapFunction).collect()

但是Java Stream不支持这个,我想知道有没有什么优雅的方法可以达到同样的效果。

【问题讨论】:

  • 你能把doSomething操作移到mapFunction里面吗?
  • 为什么不把forEach换成map

标签: java stream


【解决方案1】:
list.stream().peek(doSomething).map(mapFunction).collect()

【讨论】:

  • 这个解决方案看起来不错,但我想知道为什么它被称为 peek()。它是为了应对这种情况而设计的吗?
  • 是的,您可以阅读此方法的 javadoc。它是为制作这样的链而设计的: Stream.of("one", "two", "three", "four") .filter(e -> e.length() > 3) .peek(e -> System .out.println("过滤值:" + e)) .map(String::toUpperCase) .peek(e -> System.out.println("映射值:" + e)) .collect(Collectors.toList( ));
【解决方案2】:

forEachterminal operation,因此您无法继续使用流

诸如 Stream.forEach 或 IntStream.sum 之类的终端操作可能会遍历流以产生结果或副作用。终端操作执行后,流管道被视为消耗,不能再使用;

您可以将doSomething 移动到map 方法中,以便在映射期间执行

一般使用reduction operation 代替

forEach() 可以简单地替换为更安全、更高效且更易于并行化的归约操作

【讨论】:

    【解决方案3】:

    您不能在forEach 之后使用map,因为forEach 不会返回Stream

    您可以在 map 中使用您的 forEach 逻辑,因为它无论如何都会迭代您的整个集合:

    list.stream().map(o -> {
        // Foreach logic
        System.out.println(o);
                
        // Map
        return o.toString();
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-09-22
      • 1970-01-01
      • 2018-11-10
      • 1970-01-01
      • 2020-09-19
      • 2019-07-10
      • 1970-01-01
      • 2020-01-24
      相关资源
      最近更新 更多