IntelliJ调试Java 8流
1. 简介
自 Java 8 推出以来,很多人开始使用(新的)流功能。当然,有时我们的流操作无法按预期工作。 IntelliJ 除了正常的调试选项 外,还有一个专用的流调试功能。在这个简短的教程中,我们将探索这个伟大的功能。
2. 流跟踪对话框
让我们首先展示如何打开 Stream Trace 对话框。在调试窗口的工具栏中,有一个Trace Current Stream Chain 图标,该图标仅在我们的应用程序在流 API 调用内的断点处暂停时启用:
单击该图标将打开 Stream Trace 对话框。
该对话框有两种模式。我们将在第一个示例中查看平面模式。而且,在第二个示例中,我们将展示默认模式,即拆分模式。
3. 例子
现在我们已经在 IntelliJ 中介绍了流调试功能,是时候使用一些代码示例了。
3.1. 排序流的基本示例
让我们从一个简单的代码片段开始,以适应 Stream Trace 对话框:
int[] listOutputSorted = IntStream.of(-3, 10, -4, 1, 3)
.sorted()
.toArray();
最初。我们有一个无序的int流。接下来,我们对该流进行排序并将其转换为数组。
当我们在 Flat Mode 中查看 Stream Trace 时,它向我们展示了发生的步骤的概述:
在最左边,我们看到了初始流。它按照我们编写它们的顺序包含int。
第一组箭头向我们展示了排序后所有元素的新位置。在最右边,我们看到了我们的输出。所有项目都按排序顺序显示在那里。
现在我们已经了解了基础知识,是时候举一个更复杂的例子了。
3.2. 使用flatMap和filter的示例
下一个示例使用flatMap 。 例如,Stream.flatMap可以帮助我们将Optional 列表转换为普通列表。在下一个示例中,我们从Optional Customer的列表开始。然后我们将其映射到Customer的列表并应用一些过滤:
List<Optional<Customer>> customers = Arrays.asList(
Optional.of(new Customer("John P.", 15)),
Optional.of(new Customer("Sarah M.", 78)),
Optional.empty(),
Optional.of(new Customer("Mary T.", 20)),
Optional.empty(),
Optional.of(new Customer("Florian G.", 89)),
Optional.empty()
);
long numberOf65PlusCustomers = customers
.stream()
.flatMap(c -> c
.map(Stream::of)
.orElseGet(Stream::empty))
.mapToInt(Customer::getAge)
.filter(c -> c > 65)
.count();
接下来,让我们查看拆分模式下的 Stream Trace,它可以让我们更好地了解这个流。
在左侧,我们看到了输入流。接下来,我们看到Optional客户流到实际当前客户流的平面映射:
之后,我们将客户流映射到他们的年龄:
下一步将我们的年龄流过滤为大于 65 岁的年龄流:
最后,我们计算年龄流中的项目数:
4. 注意事项
在上面的示例中,我们看到了 Stream Trace 对话框提供的一些可能性。但是,有一些重要的细节需要注意。它们中的大多数是流如何工作的直接结果。
首先,流总是需要执行终端操作。这在使用 Stream Trace 对话框时没有什么不同。此外,我们必须注意不消耗整个流的操作——例如,anyMatch。在这种情况下,它不会显示所有元素——只显示已处理的元素。
其次,请注意流将被消耗。如果我们将Stream与其操作分开声明,我们可能会遇到错误“Stream 已被操作或关闭” 。我们可以通过将流的声明与其用法结合起来来防止此错误。