Arrays.asList () a Collections.singletonList ()

136

Czy używanie Arrays.asList (czegoś) w porównaniu z Collections.singletonList (coś) ma przewagę (lub dużą różnicę) w tworzeniu listy zawierającej jeden element? To drugie sprawia, że ​​zwracana lista jest również niezmienna.

Howard Grimberg
źródło
8
Możesz również wrzucić guawę ImmutableList.of()i Lists.newArrayList()mieszankę.
biziclop
Poza tym miałem problemy z Collections.singletonList (), gdy metoda zwraca listę, która jest później modyfikowana w dół.
Howard Grimberg
1
Java 10 ma prawdziwą niezmienną listę: stackoverflow.com/a/52536126/1216775
akhil_mittal

Odpowiedzi:

205

Collections.singletonList(something)jest niezmienna podczas gdy Arrays.asList(something)jest Listreprezentacją o stałym rozmiarze Array, w której Lista i Array są łączone w stercie.

Arrays.asList(something)umożliwia zmiany niekonstrukcyjne wprowadzone w nim, które są odzwierciedlane zarówno w Liście, jak i w połączonej tablicy. RzucaUnsupportedOperationException do dodawania, usuwania elementów, chociaż można ustawić element dla określonego indeksu.

Wszelkie zmiany dokonane na liście zwróconej przez Collections.singletonList(something)spowodują UnsupportedOperationException.

Ponadto pojemność listy zwracana przez Collections.singletonList(something)zawsze będzie wynosić 1, w przeciwieństwie do Arrays.asList(something)pojemności, której wielkość będzie wielkością tablicy obsługiwanej.

Kumar Abhinav
źródło
63

Dodam tylko, że lista singleton nie jest poparta tablicą i ma tylko odniesienie do tego jednego elementu. Prawdopodobnie zajmie to mniej pamięci i może być znaczące w zależności od liczby list, które chcesz utworzyć.

uczeń
źródło
Jakieś łącze lub kod wspierający ten punkt wydajności pamięci? Mam ten Arrays.asList (ONLY_ONE_OBJECT) napisany w dużej mierze w bazie kodu i chciałbym się dowiedzieć, czy zastąpienie go przez Collections.singletonList () prowadzi do wydajności pamięci?
Rahul Saini
12

Metoda Arrays.asListzwraca listę o stałym rozmiarze wspieraną przez określoną tablicę. Sposób powraca instancją ArrayListktóry jest prywatny zagnieżdżone klasy statyczne rozszerzenie AbstractListnie java.util.ArrayList. Ta statyczna klasa zapewnia implementację kilku metod, np. set, indexOf, forEach, replaceAllItp., Ale kiedy wywołujemy, addnie ma własnej implementacji, raczej AbstractListwywoływana jest metoda from, która rzuca java.lang.UnsupportedOperationException.

Collections.singletonListZwraca listę niezmienny zawierająca tylko określony obiekt i to jest serializacji jak również.

Na marginesie, w przypadku list niezmiennych zwykle używamy, Collections.unmodifiableListktóra zwraca niemodyfikowalny widok określonej listy.

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

Niemodyfikowalna kolekcja widoków to kolekcja, której nie można modyfikować i która jest również widokiem kolekcji zapasowej. Zwróć uwagę, że zmiany w kolekcji zapasowej mogą nadal być możliwe, a jeśli wystąpią, są widoczne w widoku niemodyfikowalnym.

Możemy mieć prawdziwą niezmienną listę w Javie 10 i nowszych. Istnieją dwa sposoby uzyskania listy naprawdę niemodyfikowalnej :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Jeśli używana jest którakolwiek z tych dwóch zmiennych, wartością nadal będzie „Apple”, a nie „Apricot”.

Jak na dok z Jawy 10 :

Metody List.ofi List.copyOfstatic factory zapewniają wygodny sposób tworzenia niemodyfikowalnych list. Wystąpienia List utworzone za pomocą tych metod mają następujące cechy:

  1. Nie można ich modyfikować . Elementów nie można dodawać, usuwać ani zastępować. Wywołanie dowolnej metody mutatora z listy zawsze spowoduje UnsupportedOperationExceptionwyrzucenie. Jeśli jednak zawarte elementy są same w sobie zmienne, może to spowodować zmianę zawartości listy.
  2. Nie zezwalają na puste elementy. Próby utworzenia ich z pustymi elementami skutkująNullPointerException .
  3. Można je serializować, jeśli wszystkie elementy można serializować.
  4. Kolejność elementów na liście jest taka sama, jak kolejność podanych argumentów lub elementów w podanej tablicy.
  5. Oni są value-based. Wzywający nie powinni przyjmować żadnych założeń dotyczących tożsamości zwracanych instancji. Fabryki mogą tworzyć nowe instancje lub ponownie wykorzystywać istniejące. W związku z tym operacje wrażliwe na tożsamość w tych wystąpieniach (równość odwołań (==), kod skrótu tożsamości i synchronizacja) są zawodne i należy ich unikać.
  6. Są one serializowane zgodnie z opisem na stronie Serialized Form .
akhil_mittal
źródło