В чем разница между списком.из и массивов.Аслан?
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 (рамки коллекций), она позволяетnulls.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 элементы.