Объявление объекта ArrayList окончательным для использования в файле констант

Я создаю список объектов ArrayList. Ниже приведен код

ArrayList someArrayList = new ArrayList();

Public ArrayList getLotOfData()
{
ArrayList someData = new ArrayList();
return someData; 
}


someArrayList = eDAO.getLotOfData();

Когда у меня есть этот объект ArrayList "someArrayList", я хотел бы объявить его общедоступным и окончательным и сохранить в файле констант, чтобы к нему можно было получить доступ глобально. Как я могу это сделать? Если я объявлю объект Arraylist общедоступным и окончательным, я не смогу переназначить ему какие-либо значения. Я пробовал следующее

public final ArrayList anotherArrayList = new ArrayList();

anotherArrayList.addAll(someArrayList);

Я надеялся сохранить этот «anotherArrayList» как глобальный объект ArrayList и использовать его, но это возвращает исключение нулевого указателя. Я хочу использовать его как строковую константу «ConstantsFile.anotherArrayList». Любые идеи???


person Raghu    schedule 14.02.2012    source источник
comment
может кто-нибудь отредактировать это?   -  person Paul Nikonowicz    schedule 15.02.2012
comment
Вы на самом деле немного запутались; объявление переменной final означает только то, что вы не можете установить ссылку на что-то еще, а не то, что вы не можете добавлять к ней объекты.   -  person Dave Newton    schedule 15.02.2012
comment
@ Дэйв ... Я также удивлен, почему это возвращает исключение nullpointer   -  person Raghu    schedule 15.02.2012
comment
Позвольте мне прямо сказать: у вас есть исключение NullPointerException, и вместо того, чтобы смотреть на трассировку стека или отладку, чтобы выяснить, что является нулевым, вы обращаетесь к stackoverflow, чтобы написать свой код для вас. Гораздо лучше задать вопрос, как определить причину исключения NullPointerException - конечно, при условии, что на вопросы не давали ответа снова и снова.   -  person meriton    schedule 15.02.2012
comment
@Raghu Почему то, что возвращает NPE?   -  person Dave Newton    schedule 15.02.2012
comment
@Raghu Ты примешь ответ? Если ни один из ответов не является приемлемым, укажите, что еще вы хотите получить от ответа.   -  person Bohemian♦    schedule 20.02.2012


Ответы (4)


Guava предоставляет _ 1_ как раз по этой причине. (Кроме того, у него нет ненужных накладных расходов на пространство, которые ArrayList выделяет, чтобы освободить место для будущих элементов, которые вы не будете добавлять для своего приложения.)

public static final ImmutableList<String> CONSTANTS = 
  ImmutableList.of("foo", "bar");
person Louis Wasserman    schedule 14.02.2012

Вы можете легко сделать это public static final, но это не помешает людям изменить содержимое.

Наилучший подход - безопасно опубликовать "константу" с помощью:

  • завернуть его в неизменяемый список
  • используя экземплярный блок для его заполнения

В результате получилось одно аккуратное финальное объявление с инициализацией:

public static final List<String> list = Collections.unmodifiableList(
    new ArrayList<String>() {{
        add("foo");
        add("bar");
        // etc
    }});

или аналогичный, но другой стиль для простых элементов (которым не нужен код)

public static final List<String> list = 
    Collections.unmodifiableList(Arrays.asList("foo", "bar"));
person Bohemian♦    schedule 14.02.2012

Совместимость с Java 1.4:

public static final List STRINGS = Collections.unmodifiableList(
    Arrays.asList(new String[] {"foo", "bar"}));

Такой список нельзя изменить, вызов таких методов, как add(), remove() или set() вызовет UnsupportedOperationException.

Для менее древних версий Java:

public static final List<String> STRINGS = Collections.unmodifiableList(
    Arrays.asList("foo", "bar"));

И наконец, в Java 9 есть:

public static final List<String> STRINGS = List.of("foo", "bar");
person Natix    schedule 14.02.2012

Вот еще один способ создать окончательный список ArrayList, а затем сделать его неизменяемым. Это включает в себя создание класса для хранения последнего списка ArrayList.

Сначала составьте свой список, сделав все необходимые вам мутации.

Во-вторых, создайте класс, который будет создавать последний список ArrayList в своем конструкторе.

public class Wrapper {

    final List<T> list;
   
    // Other final variables to be set and added to the constructor.

    public Wrapper(List<T> list) {
        this.list = Collections.unmodifiableList(list);
    }

}

Это полезно, когда вам нужен неизменяемый класс со списком.

person John Glen    schedule 26.08.2020
comment
Это то, что делает Collections.unmodifiableList() - возвращает обертку. Использование этого класса не добавляет значения: т.е. new Wrapper(myList) фактически то же самое, что Collections.unmodifiableList(Collections.unmodifiableList(myList)). Почему вызывающий должен использовать ваш класс, а не просто Collections.unmodifiableList(myList)? Также обратите внимание, что создание поля final не требуется - достаточно не указывать установщик. - person Bohemian♦; 27.08.2020
comment
Когда вам нужен неизменяемый класс со списком. Указанный неизменяемый класс может иметь любое количество членов. - person John Glen; 27.08.2020
comment
Что делать, если вам нужно два списка? Или 100? Логический подход состоит в том, чтобы использовать несколько Wrapper, а затем мы вернемся к использованию просто Collections.unmodifiableList(). Во всяком случае, это на самом деле не отвечает на вопрос, который спрашивает, как объявить неизменяемый список строк, который является константой. - person Bohemian♦; 27.08.2020
comment
Что, если вам нужны не члены списка в оболочке? - person John Glen; 28.08.2020