lambda 内赋值外部变量编译器提示:lambda表达式中使用的变量应为 final 或有效 final
需求目标
列表按照正序排序,需要标记出第一条记录。考虑的是设置一个 bool 变量,默认为 true,在第一条标记后更新为 false。
List<SpUser> spUserList = xxMapper.selectSpUserList(xx);
boolen isFirst = true;
spUserList.forEach(spUser -> {
SpApplyRecord spApplyRecord = new SpApplyRecord();
spApplyRecord.setApplyId(spApply.getId());
spApplyRecord.setUserId(spUser.getUserId());
spApplyRecord.setUserName(spUser.getUserName());
if (isFirst) { // 提示显示位置
isFirst = false; // 提示显示位置
spApplyRecord.setState(SpApplyRecordStateEnum.AUDITING.getCode());
} else {
spApplyRecord.setState(SpApplyRecordStateEnum.TO_AUDIT.getCode());
}
spApplyRecordList.add(spApplyRecord);
});
此时提示 lambda 表达式中使用的变量应为 final 或有效 final
。百度了一下意思,lambda 表达式内可以使用外部的局部变量,但不可以修改值。final 修复符就表示变量值在第一次初始化之后不会更改。
解决方法
2024.09.12
最近又发现一种方法,如果是数据类型的变量,可以将其改成包装类,这样就就可以了。
比如 int
改成 Integer
,bool
改成 Boolen
,String... String 好像不用改。
——————————
网上提到不修改,或者使用 final 修饰,但这里需要修改变量值。
最终汇总有两种方法,一种是使用数组或集合。数组或集合本身属于引用类型,修改其内部元素值,引用是不会变的。
另一种是原子(原子是什么?不太清楚)。这是编辑器提供的另一种解决方法,具体用法如下:
List<SpUser> spUserList = xxMapper.selectSpUserList(xx);
AtomicBoolean isFirst = new AtomicBoolean(true);
spUserList.forEach(spUser -> {
SpApplyRecord spApplyRecord = new SpApplyRecord();
spApplyRecord.setApplyId(spApply.getId());
spApplyRecord.setUserId(spUser.getUserId());
spApplyRecord.setUserName(spUser.getUserName());
if (isFirst.get()) {
isFirst.set(false);
spApplyRecord.setState(SpApplyRecordStateEnum.AUDITING.getCode());
} else {
spApplyRecord.setState(SpApplyRecordStateEnum.TO_AUDIT.getCode());
}
spApplyRecordList.add(spApplyRecord);
});
其他的原子类型还有 AtomicInteger、AtomicLong 之类的。