当前位置: 首页 > 科技观察

Java8中使用Stream的缺点是调试困难?教你一招,你就不会这么想了

时间:2023-03-12 08:07:36 科技观察

今天给大家分享一下如何在IntellJIDEA中调试Java8,它带来了牛逼的新特性Stream。前面写的Java8API增加了一个新的抽象,叫做流Stream,它允许你以声明的方式处理集合数据。StreamAPI可以大大提高Java程序员的工作效率,让我们写出高效、干净、简洁的代码。这种风格把待处理的元素集合看成一个流,在管道中传输,可以在管道的节点上进行处理,如过滤、排序、聚合等,元素流通过中间操作处理在流水线中,最后通过终端操作得到前面处理的结果。+--------------------++-----++-----++---++-------+|streamofelements+----->|filter+->|sorted+->|map+->|collect|+--------------------++------++------++---++--------+上面的过程转换成Java代码:ListtransactionsIds=widgets.stream().filter(b->b.getColor()==RED).sorted((x,y)->x.getWeight()-y.getWeight()).mapToInt(Widget::getWeight).sum();Java代码这样写,表达的意思也很明确,别写得太顺眼哦~反正我们项目组升级到Java8后,一般涉及到集合遍历、元素转换、过滤、排序、统计等。我的反手是Stream。我身边的同事基本都是这么用的,因为写的很流畅,感觉也很好~痛点之前面试阿里的时候,二面的面试官问Java8有什么新特性?其中,我提到了Java8带来的Stream,然后他问了有什么缺点?我回答说写的代码很难调试,因为不像for循环,你可以在每个换行点调试。在Java7中,我们可以使用如下代码来计算空串的个数://计算空串Liststrings=Arrays.asList("abc","","bc","efg","abcd","","jkl");System.out.println("List:"+strings);intcount=0;for(Stringstring:strings){if(string.isEmpty()){count++;}}returncount;调试时直接在循环中打断点,以Debug模式运行,可以跟踪代码的执行过程:来,我们看Java8中的实现代码:System.out.println("UseJava8:");count=strings.stream().filter(string->string.isEmpty()).count();System.out.println("空字符串个数为:"+count);就一行代码,我们怎么需要断点调试呢?如上图所示,在这行Stream代码的断点处,如果选择Line,则无法调试,无法跟踪流水线中的Stream传输和流水线节点上执行的filter处理动作。选择一个断点添加到lambda表达式中,然后使用单步调试进入。不得不说IDEA真的很强大👍🏻。在我的印象中,之前使用2019版本的断点时并没有出现这个提示。反正2020以上的版本肯定有,断点的时候会提示选择。虽然可以调试,可以解决问题,但是强度不够。别眨眼,更强大更直观的视图将帮助我们对Stream的处理过程一目了然。可视化追踪Stream链的步骤还是和上面一样。打断点,在Debug模式下运行程序。不同的是,打断点时不需要选择是直线端点还是lambda表达式。选择只需要打断点:点击图形按钮,会自动打开Stream处理过程视图,整个处理过程一目了然。视图分为三部分,左边是初始采集数据,中间是流处理和过滤后的数据,右边是最终运行结果得到的处理。这样Java8Stream相关的API(过滤,排序,聚合)操作可以直观的展示出来,非常方便调试。排错的时候是不是一眼就能看出问题所在。你觉得这东西闻起来好闻吗?