# 分析 Java Stream 操作

> For the complete documentation index, see [llms.txt](https://www.jetbrains.com/zh-cn/help/idea/llms.txt).

> **TL;DR**
> 调试工具窗口：  `视图 | 工具窗口 | 调试`  或 `Alt+5` (Windows), `⌘ 5` (macOS), `⌘ 5` (IntelliJ IDEA Classic (macOS)), `⌘ 5` (macOS System Shortcuts), `Alt+5` (XWin), `Alt+5` (GNOME), `Alt+5` (KDE), `Alt+5` (Emacs), `Alt+5` (Sublime Text), `⌘ 5` (Sublime Text (macOS)), `Alt+5` (Visual Studio), `⌘ 5` (Visual Studio (macOS)), `Alt+5` (NetBeans), `Alt+5` (Eclipse), `⌘ 5` (Eclipse (macOS))

Procedure: 安装 Java Stream 调试器插件

此功能性依赖于 [Java Stream 调试器](https://plugins.jetbrains.com/plugin/9696-java-stream-debugger) 插件，需要安装并启用该插件。

1. 按 `Ctrl+Alt+S` (Windows), `⌘ Comma` (macOS), `⌘ Comma` (IntelliJ IDEA Classic (macOS)), `⌘ Comma` (macOS System Shortcuts), `Ctrl+Alt+S` (XWin), `Ctrl+Alt+S` (GNOME), `Ctrl+Alt+S` (KDE), `Ctrl+Alt+S` (Emacs), `Ctrl+Alt+S` (Sublime Text), `⌘ Comma` (Sublime Text (macOS)), `Ctrl+Alt+S` (Visual Studio), `⌘ Comma` (Visual Studio (macOS)), `Ctrl+Alt+S` (NetBeans), `Ctrl+Alt+S` (Eclipse), `⌘ Comma` (Eclipse (macOS)) 打开设置，然后选择  `插件` 。

2. 找到  Java Stream 调试器  插件，然后点击   安装  。 如果出现提示，请重启 IDE。

Java Stream 有时可能难以调试。 这是因为它们在幕后执行处理逻辑，这可能会使跟踪特定值的派生方式变得复杂。 为了帮助您调试 Java Streams，IntelliJ IDEA 可让您直观查看 Java Stream 中发生的情况。

> **Note:**
> 此功能仅适用于项目文件。 Java Stream 调试器无法与库或反编译代码一起使用。

让我们用一个用函数式编写的简单程序来演示这项功能的工作原理。

```JAVA
import java.util.stream.IntStream;

class PrimeFinder {

    static int skip = 0;
    static int limit = 100;


    public static void main(String[] args) {
        if (args.length >= 1) skip = Integer.parseInt(args[0]);
        if (args.length >= 2) limit = Integer.parseInt(args[1]);

        IntStream.iterate(1, n -> n + 1)
                .skip(skip)
                .limit(limit)
                .filter(PrimeTest::isPrime)
                .forEach(System.out::println);
    }
}

class PrimeTest {
    static boolean isPrime(int candidate) {
        return candidate == 91 || // a bug here
                IntStream.rangeClosed(2, (int) Math.sqrt(candidate))
                        .noneMatch(n -> (candidate % n == 0));
    }
}

```

正如类名所暗示的，该应用程序用于查找素数。 您可以使用程序参数来指定起始编号和要检查的候选数目。 检查逻辑由 Java 8 Stream 处理。

现在如果我们查看程序输出，会看到多余的数字。

```CONSOLE
79
83
89
91 <- extra
97

```

为了理解这些错误数字的来源，让我们使用 Stream 调试器功能。

Procedure:

1. 在使用流的行处暂停程序。 您可以使用任何流操作，包括终端操作。

```JAVA
public static void main(String[] args) {
    if (args.length >= 1) skip = Integer.parseInt(args[0]);
    if (args.length >= 2) limit = Integer.parseInt(args[1]);

    IntStream.iterate(1, n -> n + 1) // set breakpoint here
        .skip(skip)
        .limit(limit)
        .filter(PrimeTest::isPrime)
        .forEach(System.out::println);
}

```

2. 在   调试   工具窗口的工具栏中，点击   更多   ![更多按钮](https://resources.jetbrains.com/help/img/idea/2026.3/app-client.expui.general.moreVertical.svg)，然后选择   追踪当前流链   ![跟踪当前流链按钮](https://resources.jetbrains.com/help/img/idea/2026.3/java-debugger-streams.icons.stream_debugger.svg)。

3. 请使用   Stream 跟踪  对话框来分析流内的操作。 顶部的选项卡让您可以在特定操作之间切换，并查看每个操作是如何转换这些值的。

![流跟踪对话框](https://resources.jetbrains.com/help/img/idea/2026.3/debug_analyze_streams_2.png)

> **Tip:**
> 要一次性获得所有转换的全局视图，请点击   扁平模式  。 没有返回值的终端操作（如  `forEach` ）不会显示在   扁平模式   中。

对 Stream 的检查显示，额外的值来自  `过滤器`  操作。 错误的搜索现在缩小到  `谓词`  的  `过滤器` ，或更具体地说，是  `PrimeTest.isPrime()`  方法。

> **Note:**
> Stream 跟踪不会超出 Stream 的终端操作。 这意味着，如果有进一步的链式调用，例如使用  `Optional` ，它将不会在   Stream 跟踪   对话框中可见。

