Java内部类引用局部变量报错,如何在ArrayList初始化时添加index值?
问题解答
报错原因
你用的new ArrayList<Integer>(){{ add(index); }}是双大括号初始化语法,本质是创建了ArrayList的匿名子类,而Java规定:匿名内部类引用的局部变量必须是final或者有效final(即变量初始化后不再被修改)。你的index在循环中会被index+=1不断修改,不符合这个要求,因此触发报错。
初始化阶段完成添加的可行方案
方案1:将当前index值转为有效final变量
把循环中当前的index值存到一个临时的、不再修改的变量里,再在双大括号初始化块中引用这个变量:
int index=0; for (int i:nums){ if (!map.containsKey(i)){ final int currentIndex = index; // 临时变量仅初始化一次,满足有效final要求 ArrayList<Integer> al1=new ArrayList<Integer>(){{ add(currentIndex); }}; map.put(i,al1); } index+=1; }
方案2:用List.of()初始化(Java 9+)
避开匿名内部类,直接用List.of()创建包含当前index的列表,再转成ArrayList,这也是在初始化阶段完成元素添加:
int index=0; for (int i:nums){ if (!map.containsKey(i)){ ArrayList<Integer> al1 = new ArrayList<>(List.of(index)); map.put(i,al1); } index+=1; }
如果使用Java 8,可以用Arrays.asList(index)替代List.of(index),Arrays.asList返回的固定大小列表完全可以用来初始化ArrayList。
方案3:Stream收集初始化(Java 8+)
通过Stream将单个元素收集为ArrayList,同样在初始化阶段完成添加:
import java.util.stream.Collectors; import java.util.stream.Stream; // ... int index=0; for (int i:nums){ if (!map.containsKey(i)){ ArrayList<Integer> al1 = Stream.of(index) .collect(Collectors.toCollection(ArrayList::new)); map.put(i,al1); } index+=1; }
总结
双大括号初始化的核心限制来自匿名内部类的变量引用规则,要么通过临时变量满足有效final要求,要么换用不需要匿名内部类的初始化方式,都能实现在初始化阶段完成index值的添加。
内容的提问来源于stack exchange,提问作者Gyanesh Sharma
相关产品推荐
相关产品推荐

