В чем разница между списком.из и массивов.Аслан?
Java 9 представила новые методы фабрики коллекции,List.of
:
List<String> strings = List.of("first", "second");
Итак, в чем разница между предыдущими и новыми опциями? То есть, в чем разница между этим:
Arrays.asList(1, 2, 3);
и так:
List.of(1, 2, 3);
3 ответа:
Arrays.asList
возвращает изменяемый список, в то время как список, возвращенныйList.of
непреложно:List<Integer> list = Arrays.asList(1, 2, null); list.set(1, 10); // OK List<Integer> list = List.of(1, 2, 3); list.set(1, 10); // Fails
Arrays.asList
позволяет нулевые элементы в то время какList.of
нет:List<Integer> list = Arrays.asList(1, 2, null); // OK List<Integer> list = List.of(1, 2, null); // Fails with a NullPointerException
contains
метод ведет себя по-разному с нулями:List<Integer> list = Arrays.asList(1, 2, 3); list.contains(null); // Return false List<Integer> list = List.of(1, 2, 3); list.contains(null); // Throws NullPointerException
Arrays.asList
возвращает представление переданного массива, поэтому изменения в массиве также будут отражены в списке. ИбоList.of
это не так:Integer[] array = {1,2,3}; List<Integer> list = Arrays.asList(array); array[1] = 10; System.out.println(list); // Prints [1, 10, 3] Integer[] array = {1,2,3}; List<Integer> list = List.of(array); array[1] = 10; System.out.println(list); // Prints [1, 2, 3]
различия между
Arrays.asList
иList.of
посмотреть JavaDocs и говорить Стюарт Маркс (или его предыдущие версии).
я буду использовать следующие примеры кода:
List<Integer> listOf = List.of(...); List<Integer> asList = Arrays.asList(...); List<Integer> unmodif = Collections.unmodifiableList(asList);
структурная неизменяемость (или: неизменяемость)
любая попытка структурно изменить
List.of
в результатеUnsupportedOperationException
. Это включает в себя такие операции, как добавить, set и удалить. Однако вы можете изменить содержимое объектов в списке (если объекты не являются неизменяемыми), поэтому список не является "полностью неизменяемым".это та же участь для неизменяемых списков, созданных с помощью
Collections.unmodifiableList
. Только этот список является view исходный список, поэтому он может измениться, если вы измените исходный список.
Arrays.asList
не полностью неизменный, он не имеет ограничения наset
.listOf.set(1, "a"); // UnsupportedOperationException unmodif.set(1, "a"); // UnsupportedOperationException asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
аналогично, изменение резервного массива (если вы держите его) изменит список.
структурная неизменность имеет множество побочных эффектов, связанных с защитным кодированием, параллелизмом и безопасностью, которые выходят за рамки этого ответа.
нуль враждебность
List.of
и любая коллекция с Java 1.5 не позволяетnull
как элемент. Попытка пройтиnull
как элемент или даже поиск приведет кNullPointerException
.с
Arrays.asList
это коллекция из 1.2 (рамки коллекций), она позволяетnull
s.listOf.contains(null); // NullPointerException unmodif.contains(null); // allowed asList.contains(null); // allowed
сериализованной форме
с
List.of
было введено в Java 9, и списки, созданные этим методом, имеют свою собственную (двоичную) сериализованную форму, они не могут быть десериализованы на более ранних версиях JDK (no двоичная совместимость). Однако вы можете де / сериализовать с помощью JSON, например.личность
Arrays.asList
внутренне называетnew ArrayList
, что гарантирует ссылкой неравенства.
List.of
зависит от внутренней реализации. Возвращенные экземпляры могут иметь ссылочное равенство, но поскольку это не гарантируется, вы не можете полагаться на него.asList1 == asList2; // false listOf1 == listOf2; // true or false
стоит отметить, что списки равны (через
List.equals
), если они содержат одни и те же элементы в том же порядке, независимо от того, как они были созданы или какие операции они поддерживают.asList.equals(listOf); // true i.f.f. same elements in same order
реализация (предупреждение: детали могут меняться по версиям)
если количество элементов в списке!--8--> равно 2 или меньше, элементы хранятся в полях специализированного (внутреннего) класса. Примером является список, в котором хранятся 2 элемента (частичный источник):
static final class List2<E> extends AbstractImmutableList<E> { private final E e0; private final E e1; List2(E e0, E e1) { this.e0 = Objects.requireNonNull(e0); this.e1 = Objects.requireNonNull(e1); } }
в противном случае они хранятся в массиве аналогично
Arrays.asList
.время и пространство эффективность
The
List.of
реализации, которые основаны на полях (размерsize() может возвращать константу без получения длины массива, иcontains(E e)
не требует итерационных накладных расходов.построение неизменяемого списка через
List.of
тоже быстрее. Сравните приведенный выше конструктор с 2 ссылочными назначениями (и даже с одним для произвольного количества элементов) вCollections.unmodifiableList(Arrays.asList(...));
что создает 2 списка плюс другие накладные расходы. С точки зрения пространства, вы сохраняете
UnmodifiableList
обертка плюс несколько пенни. В конечном счете, экономия вHashSet
эквивалент более убедителен.
вывод: используйте
List.of
когда вы хотите, чтобы список, который не меняется, иArrays.asList
когда вы хотите список, который может измениться (как показано выше).
давайте суммируем различия между список.из и массивы.asList
List.of
лучше всего использовать, когда набор данных меньше и не изменяется, в то время какArrays.asList
может использоваться лучше всего в случае большого и динамического набора данных.
List.of
занимает очень меньше служебного пространства, потому что он имеет реализацию на основе полей и потребляет меньше места кучи, как с точки зрения фиксированных накладных расходов, так и на основе каждого элемента. в то время какArrays.asList
возьмите больше служебного пространства, потому что при инициализации он создает больше объектов в куче.коллекция возвращенным
List.of
является неизменяемым и, следовательно, потокобезопасным при сборе, возвращаемомArrays.asList
является изменяемым и не потокобезопасным. (Неизменяемые экземпляры коллекции обычно потребляют гораздо меньше памяти, чем их изменяемые аналоги.)
List.of
не дает null иArrays.asList
позволяет null элементы.