Инициализация ArrayList эквивалентна инициализации массива

Мне известно, что вы можете инициализировать массив во время создания экземпляра следующим образом:

String[] names = new String[] {"Ryan", "Julie", "Bob"};

Есть ли способ сделать то же самое с ArrayList? Или я должен добавить содержимое отдельно с помощью array.add()?

Ответ 1

Arrays.asList может помочь здесь:

new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));

Ответ 2

Да.

new ArrayList<String>(){{
   add("A");
   add("B");
}}

На самом деле это создание класса, полученного из ArrayList<String> (внешний набор фигурных скобок делает это), а затем объявляет статический инициализатор (внутренний набор фигурных скобок). На самом деле это внутренний класс содержащего класса, поэтому он будет иметь неявный указатель this. Не проблема, если вы не хотите сериализовать ее, или вы ожидаете, что внешний класс будет собран в мусор.

Я понимаю, что Java 7 предоставит дополнительные языковые конструкции, чтобы сделать именно то, что вы хотите.

EDIT: последние версии Java предоставляют более удобные функции для создания таких коллекций и заслуживают изучения вышеописанных (предоставляемых за один раз до этих версий)

Ответ 3

Вот ближайший вы можете получить:

ArrayList<String> list = new ArrayList(Arrays.asList("Ryan", "Julie", "Bob"));

Вы можете пойти еще проще:

List<String> list = Arrays.asList("Ryan", "Julie", "Bob")

Глядя на источник для Arrays.asList, он создает ArrayList, но по умолчанию используется для списка. Таким образом, вы можете сделать это (но не надежно для новых JDK):

ArrayList<String> list = (ArrayList<String>)Arrays.asList("Ryan", "Julie", "Bob")

Ответ 4

Arrays.asList("Ryan", "Julie", "Bob");

Ответ 5

Ну, в Java нет литерального синтаксиса для списков, поэтому вам нужно сделать .add().

Если у вас много элементов, это немного многословно, но вы можете либо:

  • используйте Groovy или что-то в этом роде
  • использовать Arrays.asList(массив)

2 будет выглядеть примерно так:

String[] elements = new String[] {"Ryan", "Julie", "Bob"};
List list = new ArrayList(Arrays.asList(elements));

Это приводит к некоторому ненужному созданию объекта.

Ответ 6

Как насчет этого.

ArrayList<String> names = new ArrayList<String>();
Collections.addAll(names, "Ryan", "Julie", "Bob");

Ответ 7

Выбранный ответ: ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));

Однако его важно понять выбранный ответ, который внутренне копирует элементы несколько раз перед созданием конечного массива и что существует способ уменьшить часть этой избыточности.

Давайте начнем с понимания того, что происходит:

  • Сначала элементы копируются в Arrays.ArrayList<T>, созданный статическим factory Arrays.asList(T...).

    Это не производит тот же класс, что и java.lang.ArrayList, несмотря на то же простое имя класса. Он не реализует такие методы, как remove(int), несмотря на наличие интерфейса List. Если вы вызовете эти методы, он выкинет UnspportedMethodException. Но если вам нужен список фиксированного размера, вы можете остановиться здесь.

  • Далее Arrays.ArrayList<T>, построенный в # 1, передается конструктору ArrayList<>(Collection<T>), где вызывается метод collection.toArray() для его клонирования.

    public ArrayList(Collection<? extends E> collection) {
    ......
    Object[] a = collection.toArray();
    }
    
  • Далее конструктор решает, следует ли принять клонированный массив или скопировать его снова, чтобы удалить тип подкласса. Поскольку Arrays.asList(T...) внутренне использует массив типа T, тот самый, который мы передали в качестве параметра, конструктор всегда отвергает использование клона, если T не является чистым объектом. (Например, String, Integer и т.д. Все снова копируются, поскольку они расширяют Object).

    if (a.getClass() != Object[].class) {      
        //Arrays.asList(T...) is always true here 
        //when T subclasses object
        Object[] newArray = new Object[a.length];
        System.arraycopy(a, 0, newArray, 0, a.length);
        a = newArray;
    }
    array = a;
    size = a.length;
    

Таким образом, наши данные были скопированы 3x, чтобы явно инициализировать ArrayList. Мы могли бы получить его до 2x, если мы вынудим Arrays.asList(T...) построить массив Object [], чтобы ArrayList мог его позже принять, что можно сделать следующим образом:

(List<Integer>)(List<?>) new ArrayList<>(Arrays.asList((Object) 1, 2 ,3, 4, 5));

Или, может быть, просто добавление элементов после создания может быть наиболее эффективным.

Ответ 8

Вот как это делается с использованием свободного интерфейса op4j Библиотека Java (версия 1.1 была выпущена Dec '10): -

List<String> names = Op.onListFor("Ryan", "Julie", "Bob").get();

Это очень классная библиотека, которая экономит вам тонну времени.