Java Stream API中peek()方法使用不当引发的生产问题

早上到刚公司同事就给我发了个生产报错日志,Field 'XXX' doesn't have a default value,一看,这不就是表字段为非空字段,插入数据时该字段为空导致的么。

根据日志我定位到了写入具体的是哪张表以及组装数据的代码,示例代码:

java 复制代码
import java.util.List;

public class StudentDao {
    
    private StudentMapper studentMapper;

    public boolean saveBatch(List<StudentEntity> studentList) {
        studentList.stream().peek(studentEntity -> {
            studentEntity.setName("张三");
        });
        return studentMapper.saveBatch(studentList);
    }
}

我乍一看这代码没问题呀, 字段通过peek()方法赋值了呀,怎么还会报错呢?

文中所有peek()方法均指的是:

java 复制代码
Stream<T> peek(Consumer<? super T> action)

此时,我看到我的idea对peek()方法有个波浪线提示,我猜测有可能就是这个peek()写法有问题,于是我将光标放到peek()方法上,提示'Stream.peek()' 的结果已忽略。

当时没明白什么意思,于是我就写了个main方法,将源代码copy运行了一下,发现居然没赋值成功,字段值任然是null。

我当时一脸懵逼,我就在想难道赋值方法没执行吗?于是我就加了1行控制台输出代码并且加了个断点,重新执行后发现控制台没有输出,也没进断点。

这个peek()方法平时用的不多,也没注意去看,只知道它主要是支持调试,很少用它来对集合元素进行赋值,一般对集合元素遍历赋值都用 forEach()方法,于是百度搜了一下,发现了这个方法的真谛

peek()方法是 Strean 接口中的一个中间操作,它允许你在流的每个元素上执行一个操作,但是这个操作是在最终的终端操作执行前进行的。

然而,如果 peek()是流中唯一的操作,那么它实际上不会执行。

这是因为peek ()本身并不是一个 终端操作,它不会触发流的执行。

在Java 8及以后的版本中,流的执行是情性的,这意味着流操作不会立即执行,而是在遇到终端操作时才会实际执行。

什么是终端操作,在Stream API 中终端操作有很多方法,以下举几个例子,在Stream API中搜terminal operation 就会很清楚的发现哪些方法是终端操作了

java 复制代码
<R, A> R collect(Collector<? super T, A, R> collector);
Optional<T> min(Comparator<? super T> comparator);
Optional<T> max(Comparator<? super T> comparator);
long count();
void forEach(Consumer<? super T> action);

总结一下,就是peek()方法中的代码要执行,必须后面要跟上终端操作方法,不然代码不会执行。

问题定位了,于是乎,我连忙打开代码提交记录,先看下是谁写的代码,把问题的锅先甩出去再说(PS:此处奸笑一下),最后发现这个代码1个将近10年开发经验的老鸟写的,不过这哥们已经离职了。不过这个BUG,也算是给我这个老鸟上了一课。

相关推荐
你的冰西瓜几秒前
C++中的list容器详解
开发语言·c++·stl·list
java1234_小锋8 分钟前
Java进程占用的内存有哪些部分?
java
就不掉头发11 分钟前
I/O复用
运维·服务器·c语言·开发语言
sxlishaobin18 分钟前
Spring Bean生命周期详解
java·后端·spring
曹牧33 分钟前
Java:Assert.isTrue()
java·前端·数据库
梦里小白龙37 分钟前
JAVA 策略模式+工厂模式
java·开发语言·策略模式
安_1 小时前
js 数组splice跟slice
开发语言·前端·javascript
你不是我我1 小时前
【Java 开发日记】我们来说一说 Redis 主从复制的原理及作用
java·redis·github
程序员葫芦娃1 小时前
【Java毕设项目】基于SSM的旅游资源网站
java·开发语言·数据库·编程·课程设计·旅游·毕设
Pocker_Spades_A1 小时前
飞算Java在线学生成绩综合统计分析系统的设计与实现
java·开发语言·java开发·飞算javaai炫技赛