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

面试官问:Stream中的map、peek、foreach方法有什么区别?完全糊涂了……

时间:2023-03-20 15:37:29 科技观察

原代码是这样的:List

children=all.stream().filter(...).map((m)->{m.setChildList(getChildrens(m,all));返回m;}).collect(Collectors.toList());其中,stream使用的map映射其实还是比较推荐把map改成peek的。你可能会有这样的疑问:为什么要把map换成peek?怎么改?map和peek有什么区别?peek和foreach有什么区别?看到这里,你是不是彻底傻眼了,没问题,本文掌柜强势来分析!另外,这些问题在Java程序员的面试过程中是一定要问的。出镜率极高,Java程序员必懂。我也把这些问题整理成了小程序。peekmap和peek都是Stream提供的流处理方法。此方法的存在主要是为了支持调试,您希望在元素流过管道中的某个点时查看元素:如:@Testpublicvoid(){Stream.of("one","two","three","四").filter(e->e.length()>3).peek(e->System.out.println("过滤后的值:"+e)).map(String::toUpperCase).peek(e->System.out.println("Mappedvalue:"+e)).collect(Collectors.toList());}输出结果:Filteredvalue:threeMappedvalue:THREEFilteredvalue:fourMappedvalue:FOUR输出流元素依次过滤和映射后。如果你想在实际工作中看到某个过程的结果,它可以派上用场。可以看出,map接收Function功能接口参数(接收一个参数,返回一个参数),peek接收Consumer功能接口参数(接收一个参数,不返回任何参数)。如果你不明白,请看下面的例子:如果你有如下列表:privateListlanguageList=newArrayList(){{add("java");添加(“蟒蛇”);添加(“C++”);添加(“PHP”);添加(“去”);}};peek方法中的函数式接口参数不能有返回值:表示不能像map一样处理流中的元素,然后形成新的流:peek不能修改流中的元素,只能打印输出或其他外部可以对元素执行处理操作。但是如果流元素是引用类型,peek可以实现map的效果:privateListuserList=newArrayList(){{add(newUser("张三"));add(newUser("李四"));add(newUser("王舞"));add(newUser("赵六"));}};@Testpublicvoid(){userList.stream().peek(user->user.setName("peek:"+user.getName())).forEach(System.out::println);}输出结果:SteamPeekTest。User(name=peek:张三)SteamPeekTest.User(name=peek:李四)SteamPeekTest.User(name=peek:王五)SteamPeekTest.User(name=peek:赵六)虽然不能返回一个值形成一个新的流,它可以修改引用类型字段的值。这也是为什么fans建议把map换成peek,因为是引用类型,用peek不需要set后return。列表<菜单>子项=全部。溪流()。筛选(...)。map((m)->{m.setChildList(getChildrens(m,all));returnm;}).收集(收集器。toList());修改为:Listchildren=all.stream().filter(...).peek(m->m.setChildList(getChildrens(m,all))).collect(Collectors.toList());是不是更优雅?比如foreach的源码:和peek一样,也是接收Consumer参数。不同的是foreach不返回参数,也就是说foreach会中断流操作,只能用于遍历,不能进行后续的流处理。小结根据文章中的例子,大家应该已经弄清楚map、peek、foreach的区别和用法了。现在总结一下!map:用于映射流中的每一个元素,然后形成一个新的流;peek:用于调试调试流的中间结果,不能形成新的流,但可以修改引用类型字段的值;foreach:用于遍历会中断流操作;