【问题标题】:Java 8 Streams peek/map without collecting is not giving outputJava 8 Streams peek/map 不收集不提供输出
【发布时间】:2020-07-27 21:57:59
【问题描述】:

下面的代码没有打印任何值。没有 System.out.println() 语句被打印。我假设 peek 处理修改数据。令人惊讶的是 peek() 内部的逻辑甚至没有被执行。 如果我使用收集器收集流,我会看到所需的行为。

  • 为什么至少 print 语句 1 没有被执行?
  • 为什么外部对象(输出列表)没有附加所需的值?
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class HelloWorld {
    public static void main(String[] args) {
        List<String> input = new ArrayList<>(Arrays.asList("hello", "bye", "vacation"));
        List<String> output = new ArrayList<>();
        input.stream().peek(x -> {
            System.out.println(x+"inside"); // print statement 1
            if (x.length() > 3) {
                output.add(x.toUpperCase());
            }
        });

        output.forEach(System.out::println); // print statement 2
    }
}

【问题讨论】:

  • peek 是一个中间操作,以后没有终端操作就不会调用它
  • peek -> forEach
  • @saka1029:那么调用stream()应该省略。

标签: java collections java-8 java-stream


【解决方案1】:

代码中有几个问题:

  1. Stream 没有通过 终端操作 关闭,因此不会调用管道操作。
  2. Stream::peek 是一个中间操作,主要用于调试。
  3. 您不应该在流中使用任何副作用或有状态操作 - 调用 output.add(x.toUpperCase()); 是不好的。
  4. output 是空的,所以只要 Stream 没有关闭,就不会打印任何内容(参见第 1 条)。

您只需在package description 处了解 Stream API。最后,您可以得出如下结论:

List<String> output = input.stream()              // Stream<String>
    .peek(x -> System.out.println(x + " inside")) // print each value
    .filter(x -> x.length() > 3)                  // filter Strings longer than 3 chars
    .map(x -> x.toUpperCase())                    // make them uppercase using map
    .collect(Collectors.toList());                // to List - a terminal operation

【讨论】:

    【解决方案2】:

    当引用Stream#peek(Consumer) 时,会从现有的Stream 创建一个新的StatelessOp 对象。但是,来自 StatelessOp 对象的名为 opWrapSink 的方法仅在使用 Stream 元素时才被调用。您在任何时候都不会消耗 Stream 的元素。在文档中,推理是中间操作是惰性完成的。

    偷懒。许多流操作,例如过滤、映射、 或者去重,可以懒惰实现,暴露 优化的机会。例如,“找到第一个字符串 三个连续的元音”不需要检查所有的输入字符串。 流操作分为中间(Stream-producer) 操作和终端(产生价值或副作用的)操作。 中间操作总是惰性的。

    https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html

    【讨论】:

      猜你喜欢
      • 2015-06-19
      • 2014-04-29
      • 2023-03-21
      • 2019-10-09
      • 1970-01-01
      • 1970-01-01
      • 2018-05-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多