Arrays.asList () vs Collections.singletonList ()

135

Gibt es einen Vorteil (oder einen großen Unterschied) bei der Verwendung von Arrays.asList (etwas) gegenüber Collections.singletonList (etwas), um eine Liste mit einem Element zu erstellen? Letzteres macht die zurückgegebene Liste ebenfalls unveränderlich.

Howard Grimberg
quelle
8
Sie können Guaven ImmutableList.of()und Lists.newArrayList()in die Mischung auch werfen .
Biziclop
Abgesehen davon hatte Collections.singletonList () Probleme, wenn eine Methode eine Liste zurückgibt, die später nachgeschaltet wird.
Howard Grimberg
1
Java 10 hat echte unveränderliche Liste: stackoverflow.com/a/52536126/1216775
akhil_mittal

Antworten:

204

Collections.singletonList(something)ist unveränderlich, während Arrays.asList(something)es sich um eine ListDarstellung eines Arrays mit fester Größe handelt, bei der die Liste und das Array im Heap zusammengefügt werden.

Arrays.asList(something) erlaubt nicht strukturelle Änderungen , die sowohl in der Liste als auch im verbundenen Array angezeigt werden. Es wird UnsupportedOperationExceptionzum Hinzufügen und Entfernen von Elementen ausgelöst, obwohl Sie ein Element für einen bestimmten Index festlegen können.

Alle Änderungen an der Liste, die von zurückgegeben wurden Collections.singletonList(something) führen zu UnsupportedOperationException.

Außerdem ist die Kapazität der von zurückgegebenen Liste Collections.singletonList(something)immer 1, im Gegensatz dazu, Arrays.asList(something)deren Kapazität der Größe des gesicherten Arrays entspricht.

Kumar Abhinav
quelle
62

Ich möchte nur hinzufügen, dass die Singleton-Liste nicht von einem Array unterstützt wird und nur einen Verweis auf dieses eine Element enthält. Vermutlich würde es weniger Speicher benötigen und kann abhängig von der Anzahl der Listen, die Sie erstellen möchten, von Bedeutung sein.

Lehrling
quelle
Gibt es einen Link oder Code, der diesen Speichereffizienzpunkt unterstützt? Ich habe diese Arrays.asList (ONLY_ONE_OBJECT) weit über eine Codebasis geschrieben und möchte herausfinden, ob das Ersetzen durch Collections.singletonList () zu Speichereffizienz führt.
Rahul Saini
12

Die Methode Arrays.asListgibt eine Liste mit fester Größe zurück, die vom angegebenen Array unterstützt wird. Die Methode gibt eine Instanz zurück, bei ArrayListder es sich um eine private verschachtelte statische Klasse handelt, die erweitert wird AbstractListund nicht java.util.ArrayList. Diese statische Klasse bietet die Implementierung weniger Methoden, z set, indexOf, forEach, replaceAll. B. usw., aber wenn wir sie aufrufen add, hat sie keine eigene Implementierung, sondern es wird eine Methode von AbstractListaufgerufen, die auslöst java.lang.UnsupportedOperationException.

Das Collections.singletonListgibt eine unveränderliche Liste zurück die nur das angegebene Objekt enthält und auch serialisierbar ist.

Nebenbei bemerkt verwenden wir für unveränderliche Listen im Allgemeinen Collections.unmodifiableListeine unveränderbare Ansicht der angegebenen Liste.

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

Eine nicht modifizierbare Ansichtssammlung ist eine Sammlung, die nicht modifizierbar ist und auch eine Ansicht auf eine Hintergrundsammlung darstellt. Beachten Sie, dass Änderungen an der Hintergrundsammlung möglicherweise weiterhin möglich sind. Wenn sie auftreten, sind sie in der nicht veränderbaren Ansicht sichtbar.

Wir können eine echte unveränderliche Liste in Java 10 und höher haben. Es gibt zwei Möglichkeiten, um eine wirklich unveränderbare Liste zu erhalten :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Wenn eine dieser beiden Variablen verwendet wird, ist der Wert weiterhin "Apple" und nicht "Apricot".

Gemäß Dokument von Java 10 :

Die List.ofund List.copyOfstatische Factory - Methoden bieten eine bequeme Möglichkeit , unveränderbare Listen zu erstellen. Die mit diesen Methoden erstellten Listeninstanzen weisen die folgenden Merkmale auf:

  1. Sie sind nicht veränderbar . Elemente können nicht hinzugefügt, entfernt oder ersetzt werden. Das Aufrufen einer Mutator-Methode in der Liste führt immer UnsupportedOperationExceptionzum Auslösen. Wenn die enthaltenen Elemente jedoch selbst veränderbar sind, kann sich der Inhalt der Liste ändern.
  2. Sie verbieten Nullelemente. Versuche, sie mit Nullelementen zu erstellen, führen zu NullPointerException.
  3. Sie sind serialisierbar, wenn alle Elemente serialisierbar sind.
  4. Die Reihenfolge der Elemente in der Liste entspricht der Reihenfolge der angegebenen Argumente oder der Elemente im bereitgestellten Array.
  5. Sie sind value-based. Anrufer sollten keine Annahmen über die Identität der zurückgegebenen Instanzen treffen. Fabriken können neue Instanzen erstellen oder vorhandene wiederverwenden. Daher sind identitätssensitive Operationen auf diesen Instanzen (Referenzgleichheit (==), Identitäts-Hash-Code und Synchronisation) unzuverlässig und sollten vermieden werden.
  6. Sie werden wie auf der Seite Serialisiertes Formular angegeben serialisiert .
akhil_mittal
quelle