关于java8的List的stream流的foreach()方法问题探究(坑)与替代方案

16 篇文章 0 订阅

一、起因

今天发现线上系统出现了一个bug,

我有一个“定时任务”每天凌晨触发,任务内容:

① 定时调用的系统暴漏的接口,来定时获取List<Object>数据。
② 然后我会筛选出该List中符合条件的Object,对筛选出来的Object的某个属性进行修改
③ 最后将该List<Object>全部保存到数据库(包括修改和未修改的都保存下来)。

二、问题

发现定时执行的任务,每天触发成功了,也没有报错。但是定时任务中对List修改的值并没有全部生效。大多数都未修改成功,而偶尔修改的成功的还是获取的List<Object>中的部分数据。

三、解决

上网查阅一番,初步判断是因为使用了java8的Stream.foreach()来修改“流的源数据”导致的。官方文档中有说明:Stream (Java Platform SE 8 )

 其中,对参数有特别说明“non-interfering action to perform on the elements”,意思是说,对元素执行的非干扰动作,即foreach中执行的方法不要修改“stream流的元数据”。

而官网有对no-interfering更进一步说明java.util.stream (Java Platform SE 8 )

大概意思:

永远不应该修改流的数据源。在流管道执行期间修改流的数据源可能会导致异常、不正确的答案或不一致的行为
如果要改,则看截图中的代码示例,可以在终端操作开始之前修改源,这些修改将反映在所覆盖的元素中。

所以,如果要修改List数据

  • 方式一:
    要么就如同官网说的,在List进入Stream处理之前改。
  • 方式二:
    要么使用List<Object> newList= list.stream().map(e -> e.setXXX("123")).collect(Collection.toList);
    这种map的方式最后使用collect()接一下,保存到一个新list中如果不使用collect接收并且保存到新list中,那么有些情况下会导致对List的修改无效
  • 方式三(推荐):
    要么直接使用list.foreach(e -> e.setXXX("123"))中间不需要Stream!!中间不需要Stream!!中间不需要Stream!!

 


参考链接:

Stream (Java Platform SE 8 )

java.util.stream (Java Platform SE 8 )

list.stream().foreach()和list.foreach()的对比_初Q,的博客-CSDN博客_list.stream().foreach

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值