前言文章中的观点,来源于博客中博主一些看法,本文只是验证整理内容。 一、Stream函数会循环多少次示例代码: List<String> ages = Stream.of(17,22,35,12,37) .filter(age -> { System.out.println("filter1 处理:" + age); return age > 18; }) .filter(age -> { System.out.println("filter2 处理:" + age); return age < 35; }) .map(age -> { System.out.println("map 处理:" + age); return age + "岁"; }) .collect(Collectors.toList()); 运行结果: filter1 处理:17 filter1 处理:22 filter2 处理:22 map 处理:22 filter1 处理:35 filter2 处理:35 filter1 处理:12 filter1 处理:37 filter2 处理:37 通过结果很明显看出,stream流处理的时候,只是对列表循环了一次,然后顺序执行待定的stream语句。 二、Idea断点调试Stream代码
选择第二项,lambda调试后可以看到变量值 大部分情况,掌握这种方式,可以应付日常开发遇到stream代码逻辑调试。如果想调试查看整个Stream代码执行变化过程,必须使用“TraceCurrentStreamChain”如图: 当debug运行调试时,断点必须打在Stream开流的地方 ,然后打”TraceCurrentStreamChain”面板,f8执行调试。效果如下: 通过调试,看到stream处理每个环节的结果。比如我们以 三、Collectors.toMap关于key值重复报错平时HashMap的 put(key,value)操作时,一般很不会在意key是否已在map中存在,它会覆盖已有的数据。Stream中,使用 Collectors.toMap方法来实现的时候,如果不判断,会报错。 示例代码: List<Student> personList = new ArrayList<Student>(); personList.add(new Student("Tom", 8900, "male", "New York")); personList.add(new Student("Tom", 7000, "male", "Washington")); personList.add(new Student("Lily", 7800, "female", "Washington")); personList.add(new Student("Anni", 8200, "female", "New York")); personList.add(new Student("Owen", 9500, "male", "New York")); personList.add(new Student("Alisa", 7900, "female", "New York")); Map<String, Student> collectMap = personList.stream() .collect(Collectors.toMap(Student::getName, stu -> stu)); System.out.println("collectMap:" + collectMap); 运行后发现报错: Exception in thread "main" java.lang.IllegalStateException: Duplicate key com.project.demo.java8.Pojo.Student@42eca56e at java.util.stream.Collectors.lambda$throwingMerger$0(Collectors.java:133) at java.util.HashMap.merge(HashMap.java:1256) map转换的时候,出现了重复key,所以抛出异常。 那我们需要手动指定让toMap,按照我们的要求进行处理。 Map<String, Student> collectMap = personList.stream() .collect(Collectors.toMap(Student::getName, stu -> stu,(exist,newStu)->newStu)); System.out.println("collectMap:" + collectMap); 运行后正常打印。一般日常工作中,都是直接去重再进行转换。 四、不要用peek函数处理业务long count = personList.stream().peek(x -> log.info("peek:{}", JSONUtil.toJsonStr(x))).count(); 查看peek源码,有说明大致意思,这个方法只是用于调试、日志打印。 五、Stream关于Collectors.join存在意义一般字符串拼接,直接通过String.join可以了,但是遇到对象列表的字符串拼接,必须使用Collections.joining方法。 List<Student> personList = new ArrayList<Student>(); personList.add(new Student("Tom", 8900, "male", "New York")); personList.add(new Student("Tom", 7000, "male", "Washington")); personList.add(new Student("Lily", 7800, "female", "Washington")); personList.add(new Student("Anni", 8200, "female", "New York")); personList.add(new Student("Owen", 9500, "male", "New York")); personList.add(new Student("Alisa", 7900, "female", "New York")); String nameStrJoin = personList.stream().map(Student::getName).collect(Collectors.joining(",")); log.info("nameStrJoin:{}", nameStrJoin); 运行结果: nameStrJoin:Tom,Tom,Lily,Anni,Owen,Alisa 总结关于java8 Stream常用的方法还有很多,目前只是举例说明。遇到Stream流的断点调试,通过idea开发工具,能够更好、全面的监视运行情况。 |
|