Thread.sleep对Stream处理没有影响吗?

Arv*_*ash 3 java java-stream

以下程序来自 Jeanne Boyarsky 和 ​​Scott Selikoff 的 OCP 学习指南:

import java.util.*;

class WhaleDataCalculator {
    public int processRecord(int input) {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            // Handle interrupted exception
        }
        return input + 1;
    }

    public void processAllData(List<Integer> data) {
        data.stream().map(a -> processRecord(a)).count();
    }

    public static void main(String[] args) {
        WhaleDataCalculator calculator = new WhaleDataCalculator();
        // Define the data
        List<Integer> data = new ArrayList<Integer>();
        for (int i = 0; i < 4000; i++)
            data.add(i);
        // Process the data
        long start = System.currentTimeMillis();
        calculator.processAllData(data);
        double time = (System.currentTimeMillis() - start) / 1000.0;
        // Report results
        System.out.println("\nTasks completed in: " + time + " seconds");
    }
}
Run Code Online (Sandbox Code Playgroud)

作者声称

假设有 4000 条记录,每条记录需要 10 毫秒处理,通过使用串行 Stream(),大约需要 40 秒才能完成此任务。

然而,当我在我的系统中运行它时,每次运行需要 0.006 秒到 0.009 秒。

差异在哪里?

MC *_*ror 10

这是因为使用了count,它在后来的 Java 版本中执行了一个技巧。

由于您只对元素的数量感兴趣,count因此将尝试直接从源获取大小,并跳过大多数其他操作。这是可能的,因为您只执行 amap而不是 a filter,因此元素的数量不会改变。

如果添加peek(System.out::println),您也不会看到任何输出。

如果您调用forEach而不是count,则运行代码可能需要 40 秒。