зависит от идентификатора массива, который вы передаете, так как результирующий список является изменяемым представлением массива, отражая все изменения в двух направлениях.

9 представила новые фабричные методы для списков,List.of:

List<String> strings = List.of("first", "second");

В чем разница между предыдущим и новым вариантом? То есть какая разница между этим:

Arrays.asList(1, 2, 3);

и это:

List.of(1, 2, 3);
 ZhekaKozlov05 окт. 2017 г., 15:33
@ user1803551 В Javadocs не упоминаются различия между деталями реализации этих двух методов (такими как потребление пространства или производительность). Я думаю, что люди хотели бы знать эти детали тоже.
 user180355105 окт. 2017 г., 13:40
Смотрите также этоговорить Стюарт "Стакан" Маркс.
 Jim Fasarakis Hilliard05 окт. 2017 г., 15:23
@ user1803551 Хотя я понимаю ваше разочарование, это рассуждение может создать действительно нежелательный прецедент.Много на вопросы здесь есть ответ, который «четко сформулирован» (в зависимости от того, как это определить). Я призываю вас перенести это обсуждение в мета, но я почти уверен, что такое обсуждение уже должно существовать (и я надеюсь, что кто-то может найти его и связать его :-)
 user180355106 окт. 2017 г., 05:20
@ZhekaKozlov Ответ также не принят. Что это говорит вам о принятых стандартах? Это даже имеетМеньше информация, чем в документах (сериализация, идентификация, упорядочение). Если что, подайте запрос в OpenJDK, чтобы добавить эту информацию.
 Jim Fasarakis Hilliard06 окт. 2017 г., 09:15
Этот вопрос обсуждается намета.

Ответы на вопрос(3)

Список а такжеArrays.asList

List.of лучше всего использовать, когда набор данных меньше и неизменен, в то время какArrays.asList лучше всего использовать в случае большого и динамического набора данных.

List.of занимают очень меньше служебного пространства, потому что оно имеет полевую реализацию, и занимают меньше места в куче, как с точки зрения фиксированных служебных данных, так и для каждого элемента. покаArrays.asList занимают больше служебного пространства, потому что при инициализации он создает больше объектов в куче.

Коллекция возвращенаList.of является неизменным и, следовательно, потокобезопасным, в то время как коллекция возвращаетсяArrays.asList изменчив и не потокобезопасен. (Неизменяемые экземпляры коллекций обычно потребляют намного меньше памяти, чем их изменяемые аналоги.)

List.of не позволяетзначение NULL элементы в то время какArrays.asList позволяетзначение NULL элементы.

 ZhekaKozlov05 окт. 2017 г., 12:20
@ChrisHayes По крайней мереList.of(x) а такжеList.of(x, y) более эффективны, потому что они вообще не выделяют массивы
 Hulk05 окт. 2017 г., 11:15
«Неизменяемые экземпляры коллекций обычно потребляют намного меньше памяти, чем их изменяемые аналоги». - В самом деле? Не могли бы вы немного рассказать об этом - вы имеете в виду, что ими можно безопасно поделиться, или вы имеете в виду, что сами экземпляры могут быть реализованы как-то более эффективно?
 ZhekaKozlov05 окт. 2017 г., 11:34
@ Халк Ответчик прав насчет эффективности использования пространства. Смотрите выступление Стюарта Маркса:youtu.be/q6zF3vf114M?t=49m48s
 Chris Hayes05 окт. 2017 г., 11:40
@ZhekaKozlov Это кажется правдой в целом, но я очень скептически отношусь к этому, когда говорю оArrays.asList противList.ofучитывая, что первый буквально является просто оберткой вокруг массива. По крайней мереРеализация OpenJDK кажется, имеет очень маленькие накладные расходы. По факту,List.of потребуется сделать копии любого переданного массива, поэтому, если сам массив скоро не станет GC, может показаться, чтоList.of имеет значительно больший объем памяти.
 Holger06 окт. 2017 г., 08:39
@ Халк: не забывайте, чтоList.of методы не обязаны возвращать новые списки каждый раз. Эти списки имеют неопределенную идентификацию, поэтому на уровне JVM может выполняться кэширование, дедупликация или скаляризация. Если не в этой версии, то, возможно, в следующей. Это разрешено договором. Напротив,Array.asList зависит от идентификатора массива, который вы передаете, так как результирующий список является изменяемым представлением массива, отражая все изменения в двух направлениях.
Решение Вопроса

Arrays.asList возвращает изменяемый список, в то время как список возвращаетсяList.of являетсянеизменный:

list.set(1, 10); // OK

List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException

Arrays.asList позволяет нулевые элементы в то время какList.of нет:

 // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException

contains ведет себя по-разному с нулями:

List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false

List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with 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]
 Sandy Chapman05 окт. 2017 г., 13:22
То, что список ведет себя по-разному в зависимости от его структуры, не кажется мне слишком объектно-ориентированным. Возможно, если List.of вернет тип ImmutableList, это будет иметь смысл. Это очень дырявая абстракция здесь.
 Sandy Chapman05 окт. 2017 г., 13:52
Я не разработчик Java, поэтому воспринимайте это как случайное наблюдение. Возможно, есть веская причина для отличия поведения, но если бы у меня был метод, возвращающий List <Integer>, как в примере, интерфейса было бы недостаточно, чтобы я знал, получу ли я исключение времени выполнения, если я его проверю для нулей. Аналогично, изменение в реализации этих методов может повлиять на код, удаленный от сайта вызова моего метода, если эта проверка произойдет в другом месте. @Nicolai
 Aaron05 окт. 2017 г., 16:04
@ SandyChapman это может быть неожиданным поведением для некоторых (или для большинства?), Но это задокументированное поведение. ИзList.contains(Object o)ага : "Выдает [...] NullPointerException - если указанный элемент является нулем, и этот список не разрешает нулевые элементы (необязательно)". Или из длинного введения интерфейса, которое читают немногие: «Некоторые реализации коллекций имеют ограничения на элементы, которые они могут содержать»
 Holger06 окт. 2017 г., 08:32
@ Санди Чепмен:List.of делает вернуть немногоImmutableList тип, его фактическое имя - просто непубличная деталь реализации. Если это было публично, и кто-то бросил этоList опять же, где была разница? Где разницаArrays.asList, который возвращает непубличныйList реализация, которая выдает исключение при попыткеadd или жеremoveили список, возвращенныйCollections.unmodifiableList который не позволяет никаких изменений вообще? Это все о контрактах, указанных вList интерфейс. Интерфейсы Коллекций с дополнительными методами всегда были нечистыми ООП начиная с Java 1.2…
 Sandy Chapman05 окт. 2017 г., 20:26
@ Аарон, по крайней мере, это хорошо документированная дырявая абстракция :)
Различия междуArrays.asList а такжеList.of

JavaDocs и этоговорить Стюарт Маркс (или предыдущие версии).

Я буду использовать следующее для примеров кода:

List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
Структурная неизменность (или: неизменяемость)

Любая попыткаструктурно менятьList.of приведет кUnsupportedOperationException, Это включает в себя такие операции, какДобавлять, установлен а такжеУдалить, Однако вы можете изменить содержимое объектов в списке (если объекты не являются неизменяемыми), поэтому список не является «полностью неизменным».

Это та же участь для неизменяемых списков, созданных сCollections.unmodifiableList, Только этот списокПосмотреть исходного списка, так что он может измениться, если вы измените исходный список.

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 (Collections Framework), она позволяетnulls.

listOf.contains(null);  // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null);  // allowed
Сериализованная форма

посколькуList.of был представлен в Java 9, и списки, созданные этим методом, имеют свою собственную (двоичную) сериализованную форму, их нельзя десериализовать в более ранних версиях JDK (нетдвоичная совместимость). Однако вы можете де / сериализовать, например, с помощью 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
Реализация (предупреждение: детали могут меняться в зависимости от версии)

Если количество элементов в спискеList.of 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.

Эффективность времени и пространства

List.of реализации, основанные на полях (размер <2), выполняются немного быстрее для некоторых операций. В качестве примеровsize() может вернуть константу без выборки длины массива, иcontains(E e) не требует дополнительных итераций.

Построение неизменяемого списка с помощьюList.of тоже быстрее. Сравните приведенный выше конструктор с 2 ссылочными присваиваниями (и даже с произвольным количеством элементов)

Collections.unmodifiableList(Arrays.asList(...));

который создает 2 списка плюс другие накладные расходы. С точки зрения пространства, вы сохраняетеUnmodifiableList обертка плюс несколько копеек. В конечном итоге экономия наHashSet эквивалентны более убедительно.

Время вывода: использованиеList.of когда вы хотите список, который не меняется иArrays.asList когда вы хотите список, который может измениться (как показано выше).

 mapeters06 окт. 2017 г., 22:44
Arrays.asList не полностью изменчив.asList.add(1); бросаетUnsupportedOperationException.
 user180355106 окт. 2017 г., 16:36
Для людей, задающихся вопросом, почему этот ответ существует, см.это.

Ваш ответ на вопрос