При попытке инициализировать ArrayList с индексом в качестве значения я сталкиваюсь с сообщением об ошибке "локальные переменные, на которые ссылается внутренний класс, должны быть окончательными или фактически окончательными в <add(index);>"
int index=0;
for (int i:nums){
if (!map.containsKey(i)){
ArrayList<Integer> al1=new ArrayList<Integer>(){{
add(index);
}};
map.put(i,al1);
}
index+=1;
}
Я знаю, что есть возможные обходные пути, когда я могу просто объявить arraylist, а затем добавить к нему значение отдельно, это работает совершенно нормально.
ArrayList<Integer> al1=new ArrayList<Integer>();
al1.add(index);
map.put(i,al1);
Но я хочу понять, есть ли способ добиться этого во время самой инициализации. Пожалуйста, помогите мне с этим. Заранее спасибо!
Спасибо @MarkRotteveel. Я не знал об этой проблеме с утечкой памяти.
Вы можете инициализировать временную переменную текущим значением index
и использовать его.
final int temp = index; // this is effectively final
ArrayList<Integer> al1=new ArrayList<Integer>(){{
add(temp);
}};
Однако в этом случае, вероятно, лучше использовать List.of
, Arrays.asList
или Collections.singletonList
.
List<Integer> al1 = List.of(index);
// or, if an ArrayList is specifically required:
ArrayList<Integer> al1 = new ArrayList<>(List.of(index));
Вероятно, лучше вообще избегать двойных фигурных скобок, так как это неидиоматический способ написания кода Java.
@markspace Я предоставил лучший метод во второй половине своего ответа.
Вы не должны использовать «инициализацию двойной скобки». Он считается анти-шаблоном, поскольку добавляет дополнительные анонимные классы и может привести к утечке памяти, потому что, если они созданы нестатическим методом, они сохранят ссылку на окружающий объект. См. также Что такое инициализация двойной скобки в Java?