如何使用IntelliJ进行Java Streams调试.docx
第
如何使用IntelliJ进行JavaStreams调试
原理
让我们从一个简单的Stream开始,我们可以在IntelliJ为其创建一个基本的Streamdebugger:
.sorted()
.collect(toList());
上面的代码创建了一个由字符串A、B、C组成的Stream。紧接着对这个Stream进行sorted()操作,从而创建了一个新的Stream(至少在Java8-10中是这样),其中的元素是第一个Stream的元素按字母排序的结果。也就是说,第二个Stream包含A、B、C三个元素。最后,这些将元素放到一个List中。
StreamStrings0=Stream.of(C,B,A//C,A,B
StreamStrings1=s0.sorted();//A,B,C
ListStringstrings=s1.collect(toList());//[A,B,C]
这大体上演示了Streamdebugger如何工作。它将一个stream管道操作分割成多个代码片段,一步一步地调用中间运算操作,从而可以保留每一步操作的元素内容以供分析。
Stream.of(C,B,A)
.peek(saveStep(0))
.sorted()
.peek(saveStep(1))
.collect(toList());//Thefinalresultissavedtostep2
注意:真正的技术实现并不是上面这样,它只是提供了很好的概览。
在IntelliJrsquo;sdebugger中有更加形象化的表示:
它简洁明了地展示了Stream管道里的每个中间操作细节,以及最后结果。
调用
想调用streamdebugger的话,首先要在Stream定义处设置断点:
然后,启动调试会话(以debug模式运行):
当到达断点时,可以按指定的按钮(可能有些不好找)来调用Streamdebugger,下面用红圈标出:
这样就打开了streamdebugger,和上文所展示的一样。
数据库Streams
我将使用Speedment(streamORM),它允许通过标准的JavaStreams操作来查询数据库,因此也能通过IntelliJ来调试操作。可以通过Speedmentinitializer来创建一个Speedment项目。
可以通过下面方式创建一个Java应用。
Speedmentapp=newSakilaApplicationBuilder()
.withPassword(sakila-password)//Replacewithyourownpassword
.build();
FilmManagerfilms=app.getOrThrow(FilmManager.class);
现在我们可以对数据库film表进行stream操作。下面是个例子:
ListFilmmap=films.stream()
.filter(Film.LENGTH.equal(60))
.sorted(Film.RATING.reversed())
.collect(toList());
代码将从所有Film(电影)对象中筛选出长度为60分钟的,然后通过Film.RATING(评级)对这些Film对象进行排序(降序),最后将所有元素放入一个List。
我们调用Streamdebugger时,会看到下面这张图:
我们可以看到,初始stream中有1000部电影。筛选操作后,只剩8部电影,紧接着排序并放到一个List。
计算统计
假设我们要计算所有PG-13级别(电影分级制度中的一种)电影的最小时长、最大时长以及平均时长。代码如下:
IntSummaryStatisticsstat=films.stream()
.filter(Film.RATING.equal(PG-13))
.mapToInt(Film.LENGTH.asInt())
.summaryStatistics(