Arrays.asList() vs Collections.singletonList()

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

Ответ 1

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

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

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

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

Ответ 2

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

Ответ 3

Метод Arrays.asList возвращает список фиксированного размера, поддерживаемый указанным массивом. Метод возвращает экземпляр ArrayList который является частным вложенным статическим классом, расширяющим AbstractList а не java.util.ArrayList. Этот статический класс обеспечивает реализацию нескольких методов, например, set, indexOf, forEach, replaceAll и т.д., Но когда мы вызываем add он не имеет собственной реализации, скорее вызывается метод из AbstractList который set, indexOf, forEach, replaceAll 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); => печатает Apple
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); => печатает Apple

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

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

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