使用IntelliJ调试使用Java Streams

流(Stream)是JDK 8 +版本 非常强大的功能,只需几行即可捕获您想要的功能的要点。但是,就像它们一切顺利时一样平滑,就像它们没有按预期行事一样令人痛苦。了解如何使用IntelliJ调试Java Streams并深入了解Stream的中间操作。

在本文中,我将在我的示例中使用Sakila示例数据库和Speedment Stream ORM

原则

让我们从一个简单的Stream开始,我们可以使用它来建立IntelliJ中的Stream调试器的基础:


 

上面的代码首先创建一个 Stream
String元素组成的初始代码 "C", "A", "B"。然后,将中间操作 sorted()应用于第一个 Stream,从而(至少在Java 8-10中)创建新的 Stream,其中初始流中的元素根据其自然顺序排序。即第二个流将包含元素 "A", "B", "C"。最后,这些元素被收集到一个 List

上面的代码相当于:


 

这基本上是Stream调试器的运行方式。它将流管道分成更小的段,逐步调用不同的中间运算符,同时保留分析的每个步骤的元素:


 

注意:这不完全是技术上如何运作,但它提供了一个很好的整体轮廓。

在VisualJ的调试器中,它看起来像这样:

stream2.png

这为每个中间操作之间的Stream管道内部发生的内容提供了清晰简洁的视图,并且还显示了Stream的最终结果。

调用

首先通过设置定义Stream的断点来调用流调试器:

breakpoint2-1024x150.png

然后,启动调试会话:

debug.png

当命中断点时,可以通过按下其指定的(并且可以说有点隐藏)按钮来调用Stream调试器,如下面的红色圆圈所示:

breakpoint-hit-1024x342.png

这将启动流调试器,如本文前面所示。

数据库流

我将使用流ORM Speedment,它允许使用标准Java Streams查询数据库,因此,这些流也可以使用IntelliJ进行调试。可以使用Speedment 初始化程序设置Speedment项目。

Java应用程序本身可以像这样设置:


 

现在,我们可以流式传输数据库表“电影”。例如这样:


 

这将过滤掉 Film长度等于60分钟的所有对象,然后 Film根据
Film.RATING(降序)对这些对象进行排序,然后将这些元素收集到一个 List

当我们调用Stream调试器时,我们将看到以下内容:

speedment_stream.png

可以看出,初始流中有1,000部电影。在过滤器操作员之后,仅留下8个薄膜,随后将其分类然后收集到a List

计算统计

假设我们想要计算所有评级电影的最小,最大和平均长度 PG-13。这可以这样做:


 

在Stream调试器中看起来像这样:

speedment_stream2-1024x543.png
可以看出,可以与Stream调试器交互并单击元素,从而突出显示它们在流管道中的路径。还可以在各个步骤的元素之间滚动。

Speedment通常会优化数据库Stream中的中间操作,并将这些步骤合并到SQL查询中。但是,当使用Stream调试器时,不会进行这样的优化,我们可以看到流管道中的所有步骤。

结论

Stream调试器是一个隐藏的gem,在使用Streams时可以提供很大的帮助。

我认为IntelliJ团队已经提出了一个非常好的功能。

在这里下载IntelliJ 。