/**
* 问题代码(只是为了重现错误,请忽略代码逻辑)
*/
@Test
public void test23(){
ArrayList<Book> list = new ArrayList<>();
list.add(new Book("魔法书","20"));
list.add(new Book("武术书","30"));
list.add(new Book("技能书","50"));
list.add(new Book("魔法书","20"));
List<Book> list2 = list;
String orgShortName;
List<Book> collect = null;
for (Book vo : list) {
if (null != vo){
orgShortName = "";
if (!StringUtils.isEmpty(orgShortName)){
// Error:(343, 83) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
// 即lambda表达式中使用的本地变量 必须是被final变量或是实际只被赋值过一次的变量
collect = list2.stream().filter(temp -> temp.getName().equals(orgShortName)).collect(Collectors.toList());
}
}
}
System.out.println(collect);
}
问题代码↑:
解决思路↓:
/**
* ERROR:"从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量"
* 即编译器要求:lambda表达式中使用的局部变量(如此处的orgShortName) 必须是被final变量或是实际只被赋值过一次的变量
* 问题分析:
* 通常为了节省开销,习惯将遍历中用到的变量声明到外边,这时编译器会认为该变量有被重复赋值的风险,故抛出异常。
* 解决方法:
* 考虑将变量声明到遍历内,骗过编译器的判断(使用该方法会使得每次遍历都声明同名变量,稍微加大了资源开销)
*/
@Test
public void test23(){
ArrayList<Book> list = new ArrayList<>();
list.add(new Book("魔法书","20"));
list.add(new Book("武术书","30"));
list.add(new Book("技能书","50"));
list.add(new Book("魔法书","20"));
List<Book> list2 = list;
//String orgShortName;
List<Book> collect = null;
for (Book vo : list) {
if (null != vo){
String orgShortName = vo.getName();
if (!StringUtils.isEmpty(orgShortName)){
// Error:(343, 83) java: 从lambda 表达式引用的本地变量必须是最终变量或实际上的最终变量
// 即lambda表达式中使用的本地变量 必须是被final变量或是实际只被赋值过一次的变量
collect = list2.stream().filter(temp -> temp.getName().equals(orgShortName)).collect(Collectors.toList());
}
}
}
System.out.println(collect);
}