详谈 Java中的list.forEach()和list.stream().forEach() 异同点

涉及的文章链接:ArrayList 循环Remove遇到的坑

一、想总结本篇博客的原因

在这里插入图片描述
在日常开发中,需要对集合数据进行或多或少的赋值修改,那么循环赋值或者做一些处理就是最常见的一种操作了,但是用习惯了stream流,所以在循环的过程中就很习惯的使用stream.forEach的方式,可是编码规范却提示用.forEach代替,这是为何呢?

二、stream.forEach 和 .forEach都所处何处?

1).forEach

去定位代码位置,就会发现其在java.lang包下,list.forEach则属于最基本的操作了。因为是基本操作,所以它并不支持并行处理,因此它在处理大量数据时可能不如Stream API高效。

2)stream.forEach

所属java.util.stream下,是Stream API的一部分,用于对流中的每个元素执行给定的操作。使用Stream API的 forEach 允许进行更多的操作,例如过滤、映射等。Stream API提供了更多的灵活性和功能,适用于处理大量数据或进行复杂的操作。

三、stream.forEach 和 .forEach 代码示例

public static void main(String[] args) {List<String> list= Arrays.asList("Sunday","Monday","TuesDay","WednesDay","ThursDay","Friday","Saturday");list.forEach(d-> System.out.println("value:"+d));list.stream().forEach(f-> System.out.println("value1:"+f));list.stream().filter(d->d.length()>3).forEach(s-> System.out.println("value3:"+s));}

在这里插入图片描述

—总结差异使用

如上demo,当时普通的循环输出的时候,idea会提示我们使用.forEach来替代.stream.forEach,因为仅仅是简单的输出或者赋值,再无其他的操纵;但是当需要对集合做一些额外处理,比如筛选的时候,我们仅仅用.forEach则满足不了需求了,需要先提前将list进行筛选,再进行forEach操作;

四、 parallelStream.forEach

1)parallelStream

表面含义理解也能晓得相比stream而言,他是一种并行的流。它通过 Fork/Join 框架来拆分任务,加速流的处理过程。Fork/Join 的框架是通过把一个大任务不断 fork 成许多子任务,然后多线程执行这些子任务,最后再 Join 这些子任务得到最终结果。

2)parallelStream.forEach demo

① 性能方向

public static void main(String[] args) {List<Integer> numberList=new ArrayList<>();for (int i=0;i<1000000;i++){numberList.add(i);}Long startTime=System.currentTimeMillis();List<Integer> parallelList=new ArrayList<>();numberList.parallelStream().forEach(d->{double powValue= Math.pow(d,3);});Long endTime=System.currentTimeMillis();System.out.println("parallel:"+(endTime-startTime));}

②准确性方向

public static void main(String[] args) {List<Integer> numberList=new ArrayList<>();for (int i=0;i<10000;i++){numberList.add(i);}System.out.println("size="+numberList.size());List<Integer> parallelList=new ArrayList<>();numberList.parallelStream().forEach(parallelList::add);System.out.println("size parallel="+parallelList.size());}

看如上代码,执行结果会是什么呢?是size和size parallel都是10000,还是其他?可以自行测试一下,我测试的结果是报错了。

size=10000
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4605at java.util.ArrayList.add(ArrayList.java:465)at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)at java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)at java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:731)at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)at java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:401)at java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:734)at java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:173)at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485)at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:650)at com.meta.image.user.service.impl.AchievementServiceImpl.main(AchievementServiceImpl.java:1159)

注:报错分析详情下篇博客。

五、stream.forEach 和 .forEach的CRUD操作

1)java.lang.UnsupportedOperationException 顺带提一嘴

public static void main(String[] args) {List<String> list= Arrays.asList("Sunday","Monday","TuesDay","WednesDay","ThursDay","Friday","Saturday");list.forEach(d->{System.out.println("value="+d);if (d.equals("ThursDay")){list.add("other");}});}
public static void main(String[] args) {List<String> list= Arrays.asList("Sunday","Monday","TuesDay","WednesDay","ThursDay","Friday","Saturday");list.stream().forEach(d->{System.out.println("value="+d);if (d.equals("ThursDay")){list.add("other");}});}

结果均是一样的

value=Sunday
value=Monday
value=TuesDay
value=WednesDay
value=ThursDay
Exception in thread "main" java.lang.UnsupportedOperationExceptionat java.util.AbstractList.add(AbstractList.java:148)at java.util.AbstractList.add(AbstractList.java:108)at com.meta.image.user.service.impl.AchievementServiceImpl.lambda$main$10(AchievementServiceImpl.java:1154)at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)at com.meta.image.user.service.impl.AchievementServiceImpl.main(AchievementServiceImpl.java:1151)

参考链接:java.lang.UnsupportedOperationException错误的根源

2)add/remove操作

① list.forEach的增删结果

public static void main(String[] args) {List<String> list= new ArrayList<>();list.add("Sunday");list.add("Monday");list.add("Tuesday");list.add("Wednesday");list.add("Thursday");list.add("Friday");list.add("Saturday");list.forEach(d->{System.out.println("value="+d);if (d.equals("Thursday")){list.add("other");}});}
public static void main(String[] args) {List<String> list= new ArrayList<>();list.add("Sunday");list.add("Monday");list.add("Tuesday");list.add("Wednesday");list.add("Thursday");list.add("Friday");list.add("Saturday");list.forEach(d->{System.out.println("value="+d);if (d.equals("Thursday")){list.remove(d);}});}

list.forEach的add和remove执行结果均报错:

value=Sunday
value=Monday
value=Tuesday
value=Wednesday
value=Thursday
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList.forEach(ArrayList.java:1262)at com.meta.image.user.service.impl.AchievementServiceImpl.main(AchievementServiceImpl.java:1158)

② stream.forEach的增删结果

public static void main(String[] args) {List<String> list= new ArrayList<>();list.add("Sunday");list.add("Monday");list.add("Tuesday");list.add("Wednesday");list.add("Thursday");list.add("Friday");list.add("Saturday");list.stream().forEach(d->{System.out.println("value="+d);if (d.equals("Thursday")){list.remove(d);}});}

remove报错:

value=Sunday
value=Monday
value=Tuesday
value=Wednesday
value=Thursday
value=Saturday
value=null
Exception in thread "main" java.lang.NullPointerExceptionat com.meta.image.user.service.impl.AchievementServiceImpl.lambda$main$10(AchievementServiceImpl.java:1160)at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1384)at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)at com.meta.image.user.service.impl.AchievementServiceImpl.main(AchievementServiceImpl.java:1158)
public static void main(String[] args) {List<String> list= new ArrayList<>();list.add("Sunday");list.add("Monday");list.add("Tuesday");list.add("Wednesday");list.add("Thursday");list.add("Friday");list.add("Saturday");list.stream().forEach(d->{System.out.println("value="+d);if (d.equals("Thursday")){list.add(d);}});}

add报错:

value=Sunday
value=Monday
value=Tuesday
value=Wednesday
value=Thursday
value=Friday
value=Saturday
Exception in thread "main" java.util.ConcurrentModificationExceptionat java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1390)at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:647)at com.meta.image.user.service.impl.AchievementServiceImpl.main(AchievementServiceImpl.java:1158)

③结果及其补救办法

报错结果可以发现 stream.forEach的remove操作是会迭代整个列表的,纵然输出结果在前,但是依旧输出了null,空指针异常了。
参考我的另一篇博客:ArrayList 循环Remove遇到的坑

所以在应用时间过程中,当真的需要对集合进行add或者remove操作的时候,切记要懂得其结果是什么。

六、 总结

程序中若是最简单的赋值操作,那么list.forEach则满足需求;若需要对list做某些处理,比如筛选,则直接用stream.forEach,何时用parallelStream呢?详情下文源码说明。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/17547.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

USST新生训练赛div2+div3题解

目录 前言题解部分B Ichihime and Triangle(800)题目大意题解代码实现 C Kana and Dragon Quest game(900)题目大意题解代码实现 J Squares and Cubes(800)题目大意题解代码实现 F Double Sort(1200)题目大意题解代码实现 I Minimize the Thickness(1100)题目大意题解代码实现 …

分布式事务解决方案(最终一致性【可靠消息解决方案】)

可靠消息最终一致性解决方案 可靠消息最终一致性分布式事务解决方案指的是事务的发起方执行完本地事务之后&#xff0c;发出一条消息&#xff0c;事务的参与方&#xff0c;也就是消息的消费者一定能够接收到这条消息并且处理完成&#xff0c;这个方案强调的是只要事务发起方将消…

自适应感兴趣区域的级联多尺度残差注意力CNN用于自动脑肿瘤分割| 文献速递-深度学习肿瘤自动分割

Title 题目 Cascade multiscale residual attention CNNs with adaptive ROI for automatic brain tumor segmentation 自适应感兴趣区域的级联多尺度残差注意力CNN用于自动脑肿瘤分割 01 文献速递介绍 脑肿瘤是大脑细胞异常和不受控制的增长&#xff0c;被认为是神经系统…

监控员工电脑的软件有哪些,不得不说这几款电脑监控软件太好用了

监控员工电脑的软件在市场上种类繁多&#xff0c;以下是几款备受好评的电脑监控软件&#xff0c;它们各自具有独特的功能和优势&#xff0c;选择前必须了解一下才能做成正确决定。 1.安企神&#xff1a; 这款软件支持7天试用测试&#xff0c;获取测试版请移驾 ↓↓↓ 安企神…

Transformer模型的简单学习

前言 Transformer 来源于一篇论文&#xff1a;Attention is all you need TRM在做一件什么事情呢&#xff1f;其实一开始它是被用于机器翻译的&#xff1a; 更详细的&#xff1a; 更详细的&#xff1a; 从上图可以看出&#xff0c;一个Encoders 下面包含了 n 个 Encoder&…

如何将 Langfuse 链接到自有 PostgreSQL 数据库并升级 PostgreSQL 版本

在本文中,我们将介绍如何将 Langfuse 应用程序链接到自有的 PostgreSQL 数据库,并升级 PostgreSQL 以支持 jsonb 类型。 前提条件 运行 CentOS 7 的服务器已安装的 PostgreSQL 9.2 或更低版本需要将 Langfuse 连接到自有数据库,并升级 PostgreSQL 以支持 jsonb 类型1. 将 La…

五款局域网监控软件良心推荐

五款局域网监控软件良心推荐 有人问我&#xff0c;能不能推荐几款好用的局域网监控软件。 我说&#xff0c;当然可以了&#xff0c;凭良心说&#xff0c;这几款软件在实用性、用户体验、隐私保护以及性价比上&#xff0c;绝对是当前最强监控软件。 1. 安企神 这款软件支持7天…

vue3(一):Vue3简介、创建vue3工程、Vue3中的响应式

目录 一.Vue3简介 1.性能提升 2.源码升级 3.拥抱ts 4.新特性 &#xff08;1&#xff09;Composition API&#xff08;组合API&#xff09;&#xff1a; &#xff08;2&#xff09;新的内置组件&#xff1a; &#xff08;3&#xff09;其他改变&#xff1a; 二.创建vue…

Postman实现批量发送json请求

最近有一个场景&#xff0c;需要本地批量调用某个接口&#xff0c;从文件中读取每次请求的请求体&#xff0c;实现方法记录一下。 1.读取请求体 在 Postman 中&#xff0c;如果你想在 Pre-request Script 阶段读取文件内容&#xff0c;比如为了将文件内容作为请求的一部分发送…

聊天宝使用技巧揭秘让您快捷回复效率翻倍

聊天宝快捷回复软件&#xff0c;推出大量实用工具&#xff0c;帮助客服能更加高效的实现快捷发送&#xff0c;一键发送&#xff0c;效果翻倍&#xff01; ​ 前言 聊天宝作为一款快捷回复工具&#xff0c;让客服免去了打字回复之苦。所以很受广大客服欢迎&#xff0c;真是一旦…

什么是“SQL注入攻击”?如何预防和应对?

一、SQL注入攻击的概念 SQL注入攻击是一种针对数据库驱动的应用程序的攻击技术&#xff0c;其中攻击者通过在应用程序的输入字段中插入或“注入”恶意的SQL代码&#xff0c;试图非法访问、操作或破坏后端数据库。当应用程序不正确地处理用户输入&#xff0c;并将其直接拼接到SQ…

废品回收小程序:回收市场下的商业机遇

随着当下大众环保意识的提升&#xff0c;回收行业收到了大众的重视&#xff0c;行业快速发展。在互联网信息技术的支持下&#xff0c;“互联网废品回收”得到了发展&#xff0c;依靠各种技术搭建互联网回收平台&#xff0c;连接到居民与商家&#xff0c;让回收变得更加简单高效…

深度解析Nginx配置文件:从全局块到upstream块的探索之旅

粉丝福利&#xff1a;微信搜索「万猫学社」&#xff0c;关注后回复「电子书」&#xff0c;免费获取12本Java必读技术书籍。 Nginx配置文件的简介 在浩瀚的互联网世界中&#xff0c;Nginx就如同一座大型交通枢纽&#xff0c;将访问者的请求精准地引导到正确的服务终点。而这一切…

【会议征稿,SPIE独立出版】第五届计算机视觉和数据挖掘国际学术会议(ICCVDM 2024)

第五届计算机视觉与数据挖掘国际学术会议&#xff08;ICCVDM 2024&#xff09;将于2024年7月19-21日在中国长春举行。此前&#xff0c;ICCVDM系列会议于2020年在中国西安、2021年在中国长沙&#xff08;线上&#xff09;、2022年在中国呼伦贝尔&#xff08;线上线下&#xff09…

基于微信小程序实现的【二手物品交易平台】后端 JAVA Springboot (内附设计LW + PPT+ 源码+ 演示视频 下载)

项目名称 项目名称&#xff1a; 基于微信小程序的二手物品交易平台 项目技术栈 该项目采用了以下核心技术栈&#xff1a; 后端框架/库&#xff1a; Java, SSM框架数据库&#xff1a; MySQL前端技术&#xff1a; 微信小程序技术其他相关技术&#xff1a; HTML, MyEclipse开发…

SQL——SELECT相关的题目(力扣难度等级:简单)

目录 197、上升的温度 577、员工奖金 586、订单最多的客户 596、超过5名学生的课 610、判断三角形 620、有趣的电影 181、超过经理收入的员工 1179、重新格式化部门表&#xff08;行转列&#xff09; 1280、学生参加各科测试的次数 1965、丢失信息的雇员 1068、产品销售分…

微信好友,如此的陌生,渐渐都成了只是人名!也许没有利益关系导致!

微信里一直聊天聊的挺好的朋友&#xff0c;不知怎么到后来却联系少了&#xff0c;最后渐渐的变成躺在微信备注里的一个陌生朋友&#xff01; 以前通过工作认识了一个朋友&#xff0c;初次见面的印象不是很深刻了&#xff0c;只记得当时给我的印象是对方很有礼貌&#xff0c;特别…

vue页面滚动条触底事件

html 滚动区域外层div添加属性 ref&#xff0c;id&#xff0c;scroll 在mounted函数中使用document设置监控div属性 在mathods中监控滚动事件

期货交易的雷区

一、做自己看不懂的行情做交易计划一样要做有把握的&#xff0c;倘若你在盘中找机会交易&#xff0c;做自己看不懂的行情&#xff0c;即便你做进去了&#xff0c;建仓时也不会那么肯定&#xff0c;自然而然持仓也不自信&#xff0c;有点盈利就想平仓&#xff0c;亏损又想扛单。…

基于C#开发web网页管理系统模板流程-主界面管理员录入和编辑功能完善

前言 紧接上篇->基于C#开发web网页管理系统模板流程-登录界面和主界面_c#的网页编程-CSDN博客 已经完成了登录界面和主界面&#xff0c;本篇将完善主界面的管理员录入和编辑功能&#xff0c;事实上管理员录入和编辑的设计套路适用于所有静态表的录入和编辑 首先还是介绍一下…