Arrays.asList () против Collections.singletonList ()

138

Есть ли преимущество (или большая разница) в использовании Arrays.asList (что-то) по сравнению с Collections.singletonList (что-то) для создания списка, содержащего один элемент? Последнее также делает возвращаемый список неизменным.

Говард Гримберг
источник
8
Вы можете бросить гуавы ImmutableList.of()и Lists.newArrayList()в смеси, а также.
Бизиклоп
В дополнение к этому, у меня были проблемы с Collections.singletonList (), когда метод возвращает список, который впоследствии изменяется в нисходящем направлении.
Говард Гримберг
1
Java 10 имеет настоящий неизменный список: stackoverflow.com/a/52536126/1216775
akhil_mittal

Ответы:

207

Collections.singletonList(something)является неизменным, тогда как Arrays.asList(something)является Listпредставлением Array фиксированного размера, где List и Array объединяются в куче.

Arrays.asList(something)позволяет вносить неструктурные изменения , которые отражаются как в List, так и в объединенном массиве. Он UnsupportedOperationExceptionдобавляет для добавления, удаления элементов, хотя вы можете установить элемент для определенного индекса.

Любые изменения, внесенные в возвращенный список, Collections.singletonList(something)приведут к UnsupportedOperationException.

Кроме того, емкость возвращаемого List Collections.singletonList(something)всегда будет равна 1, в отличие от того, Arrays.asList(something)чья емкость будет равна размеру резервного массива.

Кумар Абхинав
источник
63

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

подмастерье
источник
Любая ссылка или код для поддержки этой точки эффективности памяти? У меня есть этот Arrays.asList (ONLY_ONE_OBJECT), написанный во всей кодовой базе, и я хотел бы узнать, приводит ли замена с Collections.singletonList () к эффективности памяти?
Рахул Сайни
Arrays.asList ссылается на массив (очевидно): hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share/… Collections.singletonList: hg.openjdk.java.net/jdk8u/jdk8u/ / file / be44bff34df4 / src / share /…
Бенджамин
13

Метод Arrays.asListвозвращает список фиксированного размера, поддерживаемый указанным массивом. Метод возвращает экземпляр, ArrayListкоторый является частным вложенным статическим классом, расширяющим AbstractListи не расширяющим его java.util.ArrayList. Этот статический класс обеспечивает реализацию нескольких методов, например, set, indexOf, forEach, replaceAllи т. Д., Но когда мы вызываем addего, он не имеет собственной реализации, скорее AbstractListвызывается метод from, который выбрасывает java.lang.UnsupportedOperationException.

В Collections.singletonListвозвращаете неизменен список , содержащий только указанный объект и это сериализация , а также.

Кстати, для неизменяемых списков мы обычно используем, Collections.unmodifiableListкоторый возвращает неизменяемое представление указанного списка.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

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

У нас может быть настоящий неизменный список в Java 10 и более поздних версиях. Есть два способа получить действительно неизменяемый список :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Если используется любая из этих двух переменных, значением по-прежнему будет «Яблоко», а не «Абрикос».

Согласно документу из Java 10 :

List.ofИ List.copyOfстатические фабричные методы обеспечивают удобный способ для создания нередактируемых списков. Экземпляры List, созданные этими методами, имеют следующие характеристики:

  1. Они не поддаются изменению . Элементы не могут быть добавлены, удалены или заменены. Вызов любого метода-мутатора в Списке всегда приводит UnsupportedOperationExceptionк выбрасыванию. Однако, если содержащиеся элементы сами изменяются, это может привести к изменению содержимого списка.
  2. Они запрещают нулевые элементы. Попытки создать их с нулевыми элементами приводят к NullPointerException.
  3. Они сериализуемы, если все элементы сериализуемы.
  4. Порядок элементов в списке совпадает с порядком предоставленных аргументов или элементов в предоставленном массиве.
  5. Они есть value-based. Вызывающие абоненты не должны делать никаких предположений относительно личности возвращенных экземпляров. Фабрики могут создавать новые экземпляры или повторно использовать существующие. Поэтому чувствительные к идентичности операции в этих случаях (ссылочное равенство (==), хэш-код идентичности и синхронизация) ненадежны и их следует избегать.
  6. Они сериализуются, как указано на странице « Сериализованная форма» .
akhil_mittal
источник