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


137

Чи є перевага (чи велика різниця) у використанні Arrays.asList (щось) над Collections.singletonList (щось) для створення списку, що містить один предмет? Остання робить повернений список також незмінним.


8
Ви можете кинути і гуави, ImmutableList.of()і Lists.newArrayList()в суміш.
biziclop

На відміну від цього у мене Collections.singletonList () викликав проблеми, коли метод повертає Список, який згодом буде змінений нижче.
Говард Грімберг

1
Java 10 має істинний незмінний список: stackoverflow.com/a/52536126/1216775
akhil_mittal

Відповіді:


206

Collections.singletonList(something)є незмінним, тоді як Arrays.asList(something)є фіксованим розміром Listпредставлення масиву, де список і масив об'єднуються в купу.

Arrays.asList(something)дозволяє внести до нього неструктурні зміни , які відображаються як у списку, так і у поєднаному масиві. Він кидає UnsupportedOperationExceptionдля додавання, видалення елементів, хоча ви можете встановити елемент для певного індексу.

Будь-які зміни, внесені до Списку, що повертається, Collections.singletonList(something)призведе до UnsupportedOperationException.

Крім того, ємність списку, повернутий Collections.singletonList(something)завжди, буде 1 на відміну від того, Arrays.asList(something)чиєю ємністю буде розмір резервного масиву.


63

Я просто додам, що сингл-лист не підтримується масивом і просто посилається на цей один елемент. Імовірно, це займе менше пам'яті і може бути значним залежно від кількості списків, які ви хочете створити.


Будь-яке посилання чи код для підтримки цієї точки ефективності пам'яті? У мене цей Arrays.asList (ONLY_ONE_OBJECT) написаний значною мірою в кодовій базі, і я хотів би дізнатись, чи призводить до заміни на Collections.singletonList () ефективність пам'яті?
Рахул


12

Метод Arrays.asListповертає список фіксованого розміру, підкріплений вказаним масивом. Метод повертає екземпляр, ArrayListякий є приватним вкладеним статичним класом, що розширюється, AbstractListа не java.util.ArrayList. Цей статичний клас забезпечує реалізацію декількох методів, наприклад, set, indexOf, forEach, replaceAllтощо., Але коли ми викликаємо, addвін не має власної реалізації, а метод, з AbstractListякого викликається, який кидає 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()); Якщо використовується будь-яка з цих двох змінних, значення все одно буде "Apple", а не "Абрикос".

Згідно з документом з Java 10 :

List.ofІ List.copyOfстатичні фабричні методи забезпечують зручний спосіб для створення нередактіруемих списків. Екземпляри списку, створені цими методами, мають такі характеристики:

  1. Вони незмінні . Елементи не можна додавати, видаляти чи замінювати. Виклик будь-якого мутаційного методу у списку завжди призведе UnsupportedOperationExceptionдо того, що його кинуть. Однак, якщо елементи, що містяться, самі можуть змінюватися, це може спричинити зміну вмісту Списку.
  2. Вони забороняють нульові елементи. Спроби створити їх з нульовими елементами призводять до NullPointerException.
  3. Вони серіалізуються, якщо всі елементи серіалізуються.
  4. Порядок елементів у списку такий самий, як порядок наданих аргументів або елементів у наданому масиві.
  5. Вони є value-based. Абоненти не повинні робити жодних припущень щодо особи, що повертається. Фабрики можуть створювати нові екземпляри або використовувати повторно існуючі. Тому операції, що залежать від ідентичності на цих примірниках (рівність посилань (==), хеш-код ідентифікації та синхронізація), є ненадійними та їх слід уникати.
  6. Вони серіалізуються, як зазначено на сторінці серіалізованої форми .
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.