Локальные переменные, на которые ссылается внутренний класс, должны быть окончательными или фактически окончательными — Java

При попытке инициализировать 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);

Но я хочу понять, есть ли способ добиться этого во время самой инициализации. Пожалуйста, помогите мне с этим. Заранее спасибо!

Вы не должны использовать «инициализацию двойной скобки». Он считается анти-шаблоном, поскольку добавляет дополнительные анонимные классы и может привести к утечке памяти, потому что, если они созданы нестатическим методом, они сохранят ссылку на окружающий объект. См. также Что такое инициализация двойной скобки в Java?

Mark Rotteveel 19.02.2023 14:21

Спасибо @MarkRotteveel. Я не знал об этой проблеме с утечкой памяти.

Gyanesh Sharma 20.02.2023 11:46
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
2
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете инициализировать временную переменную текущим значением 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 19.02.2023 04:40

@markspace Я предоставил лучший метод во второй половине своего ответа.

Unmitigated 19.02.2023 04:40

Другие вопросы по теме