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

news2024/11/19 2:19:49

涉及的文章链接: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: 4605
	at 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.UnsupportedOperationException
	at 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.ConcurrentModificationException
	at 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.NullPointerException
	at 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.ConcurrentModificationException
	at 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.coloradmin.cn/o/1707829.html

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

相关文章

聚合网卡和Wondershaper限速的一些问题(速度减半问题)

首先我们来了解一下聚合网卡&#xff1a; 聚合网卡&#xff0c;又称为链路聚合组&#xff08;LAG, Link Aggregation Group&#xff09;、端口汇聚&#xff08;Port Trunking&#xff09;、以太通道&#xff08;Ethernet Bonding&#xff09;等&#xff0c;是一种网络技术&…

【OpenCV】图形绘制与填充

介绍了绘制、填充图像的API。也介绍了RNG类用来生成随机数。相关API&#xff1a; line() rectangle() circle() ellipse() putText() 代码&#xff1a; #include "iostream" #include "opencv2/opencv.hpp"using namespace std; using namespace cv…

Git和plink

安装git的话首先进入到git官网进行下载Git - Downloading Package (git-scm.com) &#xff0c;点击便会自动进行下载。 安装plink时也是根据自己电脑的版本号选择进行安装&#xff0c;我的是windows的64位&#xff0c;由此选择以上版本进行安装&#xff0c;这一个下载完成之后不…

react中子传父信息

思路是&#xff1a; 在父组件定义一个函数接受参数&#xff0c;接收的参数用于接收子组件的信息&#xff0c;把函数传给子组件&#xff0c;子组件调用父亲传来的函数并把要告诉父亲的话传到函数中&#xff0c;就实现了子传父消息 import { useState } from reactimport { use…

JavaWeb笔记整理+图解——服务器渲染技术之EL表达式与JSTL

上一篇我们讲解了什么是服务器渲染技术和jsp&#xff0c;今天我来整理一下EL表达式和JSTL的笔记与图解&#xff0c;让我们的jsp页面更加的简洁与可维护。 没看过上一期的小伙伴可以看上一期的笔记&#xff1a; JavaWeb笔记全整理——JSP服务器渲染技术-CSDN博客 一、EL表达式…

揭开 SOCKS5 有哪些强大的功能?

在在线隐私和安全领域&#xff0c;SOCKS5 是一种多功能且功能强大的协议&#xff0c;为用户提供了一种无缝的方式来加密他们的互联网流量、绕过防火墙并以增强的匿名性和灵活性访问网络。无论您是担心在线监控、地理封锁还是数据隐私&#xff0c;了解如何利用 SOCKS5 的功能都可…

Apache-Doris单机部署

参考&#xff1a; 快速体验 Apache Doris - Apache Doris 1、Apache Doris是一款 基于MPP架构的高性能、实时的分析型数据库&#xff0c;以高效、简单、统一的特点被人们所熟知&#xff0c;仅需 亚秒级响应时间即可返回海量数据下的查询结果&#xff0c;不仅可以支持高并发的点…

ue引擎游戏开发笔记(46)——简单UI设计

1.需求分析&#xff1a; 玩家操作界面应该有基本的准星和血量显示等内容&#xff0c;告知玩家角色的基本状态。 2.操作实现&#xff1a; 1.较为简单的内容&#xff0c;在控件面板建立相应内容&#xff0c;之后链接到游戏中即可&#xff01; 2.先做准星&#xff0c;在画布上搞个…

Day 56 647. 回文子串 516.最长回文子序列

回文子串 给定一个字符串&#xff0c;你的任务是计算这个字符串中有多少个回文子串。 具有不同开始位置或结束位置的子串&#xff0c;即使是由相同的字符组成&#xff0c;也会被视作不同的子串。 示例 1&#xff1a; 输入&#xff1a;“abc”输出&#xff1a;3解释&#xf…

蓝桥杯Web开发【大学组:国赛】2022年真题

1.分一分 如果给你一个数组&#xff0c;你能很快将它分割成指定长度的若干份吗&#xff1f; 1.1 题目问题 请在 js/index.js 文件中补全函数 splitArray 中的代码&#xff0c;最终返回按指定长度分割的数组。 具体要求如下&#xff1a; 将待分割的&#xff08;一维&#x…

“星战之父”乔治・卢卡斯吐槽好莱坞“几乎没有原创思维”,AI 将“不可避免”用于电影制作

《星球大战》系列的创作者乔治・卢卡斯&#xff08;George Lucas&#xff09;在 1977 年奠定了电影制作传奇人物的地位&#xff0c;他对当今电影的状况及其发展方向有一些自己的看法。 他在 2024 年戛纳电影节上谈到了当前的电影行业。现年 80 岁的卢卡斯在接受法国媒体 Brut …

STM32建立工程问题汇总

老版本MDK&#xff0c;例如MDK4 工程内容如下&#xff1a; User文件夹中存放main.c文件&#xff0c;用户中断服务函数&#xff08;stm32f1xx.it.c&#xff09;&#xff0c;用户配置文件&#xff08;stm32f1xx_hal_conf.h&#xff09;等用户程序文件&#xff0c;或者mdk启动程序…

GIT提交:.husky/pre-commit: line 2: .husky/_/husky.sh: No such file or directory

GIT提交&#xff1a;.husky/pre-commit: line 2: .husky/_/husky.sh: No such file or directory 一些项目添加了代码提交校验和格式化&#xff0c;在windows下会忽略.husky下文件提交导致git数据丢失。 处理方案&#xff1a; 方案01&#xff1a;补齐缺失的文件 1.1 项目根…

最新斗音评论区截流拓客,自动引流【引流软件+使用教程】

面对社交媒体的蓬勃生长&#xff0c;加粉和拓展客户群成为品牌及个体的当务之急。新推出的一款技术工具恰到好处地迎合了这一需求&#xff0c;提供了一个多功能、适用性强的增粉与互动解决方案。该工具与抖音平台的所有版本兼容&#xff0c;消除了对特定版本的依赖。 利用这一…

微服务架构-聚合设计模式

微服务架构-聚合设计模式 聚合器&#xff08;Aggregator&#xff09;设计模式&#xff1a;用于将来自多个微服务的数据&#xff0c;聚合成一个统一的响应&#xff0c;提供给客户端。 聚合模式的核心思想&#xff1a;是使用一个聚合器服务&#xff08;Aggregator Service&#…

greendao实现增删改查

说明&#xff1a;最近碰到一个需求&#xff0c;在安卓上使用greendao框架&#xff0c;实现增删改查数据 效果图&#xff1a; step1: // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript {repositories {go…

26计算机操作系统408考研--操作系统处理机调度篇章(五)

文章目录 一、调度简介死锁一、调度简介 计算机系统中,处理器和内存资源会出现供不应求的情况,特别是多个I/O设备与主机交互,作业不断进入系统,或者是多个批处理作业在磁盘的后备队列中等待进入内存的情况。操作系统在管理有限的资源的同时,需要考虑如何选取进入内存的作…

破解App渠道归因难题,Xinstall助你实现精准数据追踪!

在移动互联网时代&#xff0c;App的推广和运营面临着诸多挑战。其中&#xff0c;渠道归因问题一直困扰着众多推广者。如何准确追踪用户来源&#xff0c;分析不同渠道的推广效果&#xff0c;成为了摆在推广者面前的一大难题。然而&#xff0c;有了Xinstall的出现&#xff0c;这一…

LabVIEW软件需求分析文档内容和编写指南

编写LabVIEW软件需求分析文档&#xff08;Software Requirements Specification, SRS&#xff09;是软件开发的关键步骤之一。以下是详细的内容结构、编写指南和注意事项&#xff1a; 内容结构 引言 项目背景&#xff1a;简要介绍项目背景和目的。 文档目的&#xff1a;说明需…

AI Agent教育行业落地案例

【AI赋能教育】揭秘Duolingo背后的AI Agent&#xff0c;让学习更高效、更有趣&#xff01; ©作者|Blaze 来源|神州问学 引言 随着科技的迅猛发展&#xff0c;人工智能技术已经逐步渗透到我们生活的各个方面。而随着AI技术的广泛应用&#xff0c;教育培训正引领着一场新的…