Ответ 1
Arrays.asList может помочь здесь:
new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));
Мне известно, что вы можете инициализировать массив во время создания экземпляра следующим образом:
String[] names = new String[] {"Ryan", "Julie", "Bob"};
Есть ли способ сделать то же самое с ArrayList? Или я должен добавить содержимое отдельно с помощью array.add()
?
Arrays.asList может помочь здесь:
new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21));
Да.
new ArrayList<String>(){{
add("A");
add("B");
}}
На самом деле это создание класса, полученного из ArrayList<String>
(внешний набор фигурных скобок делает это), а затем объявляет статический инициализатор (внутренний набор фигурных скобок). На самом деле это внутренний класс содержащего класса, поэтому он будет иметь неявный указатель this
. Не проблема, если вы не хотите сериализовать ее, или вы ожидаете, что внешний класс будет собран в мусор.
Я понимаю, что Java 7 предоставит дополнительные языковые конструкции, чтобы сделать именно то, что вы хотите.
EDIT: последние версии Java предоставляют более удобные функции для создания таких коллекций и заслуживают изучения вышеописанных (предоставляемых за один раз до этих версий)
Вот ближайший вы можете получить:
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")
Arrays.asList("Ryan", "Julie", "Bob");
Ну, в Java нет литерального синтаксиса для списков, поэтому вам нужно сделать .add().
Если у вас много элементов, это немного многословно, но вы можете либо:
2 будет выглядеть примерно так:
String[] elements = new String[] {"Ryan", "Julie", "Bob"};
List list = new ArrayList(Arrays.asList(elements));
Это приводит к некоторому ненужному созданию объекта.
Как насчет этого.
ArrayList<String> names = new ArrayList<String>();
Collections.addAll(names, "Ryan", "Julie", "Bob");
Выбранный ответ: 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));
Или, может быть, просто добавление элементов после создания может быть наиболее эффективным.
Вот как это делается с использованием свободного интерфейса op4j Библиотека Java (версия 1.1 была выпущена Dec '10): -
List<String> names = Op.onListFor("Ryan", "Julie", "Bob").get();
Это очень классная библиотека, которая экономит вам тонну времени.