Was ist der Unterschied zwischen
1.List<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia)); //copy
2.List<Integer> list2 = Arrays.asList(ia);
Wo ia
ist ein Array von ganzen Zahlen.
Ich habe erfahren, dass einige Operationen nicht erlaubt sind list2
. Wieso ist es so? Wie wird es gespeichert (Referenzen / Kopie)?
Wenn ich die Listen mische, list1
wirkt sich das nicht auf das ursprüngliche Array aus, list2
tut es aber . Ist aber immer noch list2
etwas verwirrend.
Wie sich ArrayList
die Aktualisierung auf eine Liste von der Erstellung einer neuen Liste unterscheidetArrayList
list1 differs from (1)
ArrayList<Integer> list1 = new ArrayList<Integer>(Arrays.asList(ia));
java
list
collections
Dineshkumar
quelle
quelle
Lists.newArrayList(ia)
erstellt eine unabhängige Kopie, genau wie die erste Option. Es ist einfach allgemeiner und besser anzusehen.Antworten:
Lassen Sie uns zunächst sehen, was dies bewirkt:
Es braucht ein Array
ia
und erstellt einen Wrapper, der implementiertList<Integer>
, wodurch das ursprüngliche Array als Liste verfügbar wird. Es wird nichts kopiert und alles, nur ein einziges Wrapper-Objekt wird erstellt. Operationen auf dem Listen-Wrapper werden an das ursprüngliche Array weitergegeben. Dies bedeutet, dass beim Mischen des Listen-Wrappers auch das ursprüngliche Array gemischt wird. Wenn Sie ein Element überschreiben, wird es im ursprünglichen Array überschrieben usw. Natürlich sind einigeList
Vorgänge im Wrapper nicht zulässig, z. B. Hinzufügen oder Wenn Sie Elemente aus der Liste entfernen, können Sie nur die Elemente lesen oder überschreiben.Beachten Sie, dass der Listen-Wrapper nicht erweitert wird
ArrayList
- es handelt sich um eine andere Art von Objekt.ArrayList
s haben ein eigenes internes Array, in dem sie ihre Elemente speichern und die Größe der internen Arrays usw. ändern können. Der Wrapper verfügt nicht über ein eigenes internes Array, sondern überträgt nur Operationen an das ihm zugewiesene Array.Auf der anderen Seite, wenn Sie anschließend ein neues Array als erstellen
Dann erstellen Sie eine neue
ArrayList
, vollständige, unabhängige Kopie des Originals. Obwohl Sie hier auch den Wrapper mit erstellenArrays.asList
, wird er nur während der Erstellung des neuen verwendetArrayList
und anschließend mit Müll gesammelt. Die Struktur dieses neuenArrayList
Arrays ist völlig unabhängig vom ursprünglichen Array. Es enthält dieselben Elemente (sowohl das ursprüngliche Array als auch diese neueArrayList
Referenz haben dieselben Ganzzahlen im Speicher), erstellt jedoch ein neues internes Array, das die Referenzen enthält. Wenn Sie es also mischen, Elemente hinzufügen, entfernen usw., bleibt das ursprüngliche Array unverändert.quelle
List<Integer>
für Ihre Variablentypen (oder Methodenargumente usw.) zu verwenden. Dadurch wird Ihr Code allgemeiner und Sie können bei Bedarf problemlos zu einer anderenList
Implementierung wechseln , ohne viel Code neu schreiben zu müssen.Nun, das liegt daran, dass das
ArrayList
Ergebnis vonArrays.asList()
nicht vom Typ istjava.util.ArrayList
.Arrays.asList()
Erstellt einenArrayList
Typ,java.util.Arrays$ArrayList
der nicht erweitert,java.util.ArrayList
sondern nur erweitert wirdjava.util.AbstractList
quelle
In diesem Fall
list1
ist vom TypArrayList
.Hier wird die Liste als
List
Ansicht zurückgegeben, dh es sind nur die Methoden an diese Schnittstelle angehängt. Daher sind einige Methoden nicht erlaubtlist2
.Hier erstellen Sie eine neue
ArrayList
. Sie übergeben ihm einfach einen Wert im Konstruktor. Dies ist kein Beispiel für Casting. Beim Casting könnte es eher so aussehen:quelle
Ich bin ziemlich spät hier, jedenfalls war eine Erklärung mit Dokumentenreferenzen besser für jemanden, der nach einer Antwort sucht.
ArrayList verfügt über eine Reihe überladener Konstruktoren
public ArrayList () - // gibt eine Arrayliste mit der Standardkapazität 10 zurück
öffentliche ArrayList (Sammlung c)
public ArrayList (int initialCapacity)
Wenn wir also das von Arrays.asList zurückgegebene Objekt, dh List (AbstractList), an den zweiten Konstruktor oben übergeben, wird ein neues dynamisches Array erstellt (diese Arraygröße nimmt zu, wenn wir mehr Elemente als seine Kapazität hinzufügen, und auch die neuen Elemente wirken sich nicht auf das ursprüngliche Array aus ) Flaches Kopieren des ursprünglichen Arrays ( Flaches Kopieren bedeutet, dass nur die Referenzen kopiert werden und kein neuer Satz derselben Objekte wie im ursprünglichen Array erstellt wird.)
quelle
oder
Die obige Anweisung fügt den Wrapper zum Eingabearray hinzu. Daher sind Methoden wie Hinzufügen und Entfernen für das Listenreferenzobjekt 'namesList' nicht anwendbar.
Wenn Sie versuchen, ein Element in das vorhandene Array / die vorhandene Liste einzufügen, erhalten Sie "Ausnahme im Thread" main "java.lang.UnsupportedOperationException".
Die obige Operation ist schreibgeschützt oder nur sichtbar.
Wir können keine Operationen zum Hinzufügen oder Entfernen im Listenobjekt ausführen. Aber
oder
In der obigen Anweisung haben Sie eine konkrete Instanz einer ArrayList-Klasse erstellt und eine Liste als Parameter übergeben.
In diesem Fall funktioniert das Hinzufügen und Entfernen von Methoden ordnungsgemäß, da beide Methoden aus der ArrayList-Klasse stammen. Daher erhalten wir hier keine UnSupportedOperationException.
Änderungen, die im Arraylist-Objekt vorgenommen wurden (Methode zum Hinzufügen oder Entfernen eines Elements in / aus einer Arraylist), werden nicht in das ursprüngliche java.util.List-Objekt übernommen.
quelle
Zuallererst ist die Arrays-Klasse eine Utility-Klasse, die no enthält. von Dienstprogrammmethoden für Arrays (dank der Arrays-Klasse hätten wir sonst unsere eigenen Methoden erstellen müssen, um auf Array-Objekte zu reagieren)
asList () -Methode:
asList
Die Methode ist eine der Dienstprogrammmethoden derArray
Klasse. Sie ist eine statische Methode. Deshalb können wir diese Methode anhand ihres Klassennamens aufrufen (wie zArrays.asList(T...a)
)ArrayList
Objekt erstellt, sondern lediglich einen Listenverweis auf ein vorhandenesArray
Objekt zurückgibt (nach Verwendung derasList
Methode werden nun zwei Verweise auf ein vorhandenesArray
Objekt erstellt).List
Objekt arbeiten, möglicherweise NICHT mit diesem Array-Objekt unter Verwendung einerList
Referenz arbeiten, wie z. B. dieArray
Größe s ist in der Länge festgelegt. Daher können SieArray
mit dieserList
Referenz (wielist.add(10)
oder) offensichtlich keine Elemente zum Objekt hinzufügen oder daraus entfernenlist.remove(10);
Andernfalls wird UnsupportedOperationException ausgelöst.Array
s-Objekts berücksichtigt (wenn Sie ein vorhandenes Array-Objekt mithilfe der Listenreferenz bearbeiten).Im ersten Fall erstellen Sie ein neues
Arraylist
Objekt (im zweiten Fall wird nur ein Verweis auf ein vorhandenes Array-Objekt erstellt, aber kein neuesArrayList
Objekt). Jetzt gibt es zwei verschiedene Objekte, eines ist einArray
Objekt und ein anderes ist einArrayList
Objekt und keine Verbindung zwischen ihnen (also Änderungen in einem Objekt wird in einem anderen Objekt nicht reflektiert / beeinflusst (dh in Fall 2Array
undArraylist
sind zwei verschiedene Objekte)Fall 1:
Fall 2:
quelle
Viele Leute haben die mechanischen Details bereits beantwortet, aber es ist erwähnenswert: Dies ist eine schlechte Design-Wahl von Java.
Javas
asList
Methode ist dokumentiert als "Gibt eine Liste mit fester Größe zurück ...". Wenn Sie das Ergebnis nehmen und die.add
Methode aufrufen (sagen wir) , wird ein ausgelöstUnsupportedOperationException
. Das ist unintuitives Verhalten! Wenn eine Methode angibt, dass sie a zurückgibtList
, wird standardmäßig erwartet, dass sie ein Objekt zurückgibt, das die Methoden der Schnittstelle unterstütztList
. Ein Entwickler sollte sich nicht merken müssen, welche der unzähligenutil.List
MethodenList
s erstellt, die nicht alleList
Methoden unterstützen.Wenn sie die Methode benannt hätten
asImmutableList
, wäre es sinnvoll. Oder wenn die Methode nur ein tatsächlichesList
Ergebnis zurückgeben würde (und das Hintergrundarray kopieren würde), wäre dies sinnvoll. Sie beschlossen, sowohl Laufzeitleistung als auch Kurznamen zu bevorzugen , auf Kosten der Verletzung sowohl des Prinzips der geringsten Überraschung als auch der guten OO-Praxis der VermeidungUnsupportedOperationException
s zu .(Auch die Designer könnten ein gemacht haben
interface ImmutableList
, um eine Fülle vonUnsupportedOperationException
s zu vermeiden .)quelle
Beachten Sie, dass in Java 8 'ia' oben Integer [] und nicht int [] sein muss. Arrays.asList () eines int-Arrays gibt eine Liste mit einem einzelnen Element zurück. Wenn Sie das Code-Snippet von OP verwenden, wird der Compiler das Problem erkennen, aber einige Methoden (z. B. Collections.shuffle ()) werden im Stillen nicht das tun, was Sie erwarten.
quelle
quelle
Arrays.asList()
Diese Methode gibt ihre eigene Implementierung von List zurück. Sie verwendet ein Array als Argument und erstellt darauf Methoden und Attribute, da keine Daten aus einem Array kopiert werden, sondern das ursprüngliche Array verwendet wird. Dies führt zu Änderungen im ursprünglichen Array, wenn Sie Änderungen vornehmen Liste, die von der
Arrays.asList()
Methode zurückgegeben wird.andererseits.
ArrayList(Arrays.asList());
ist ein Konstruktor derArrayList
Klasse, der eine Liste als Argument verwendet und eineArrayList
von der Liste unabhängige zurückgibt , d. h.Arrays.asList()
in diesem Fall als Argument übergeben. Deshalb sehen Sie diese Ergebnisse;quelle
Gibt in Zeile 2
Arrays.asList(ia)
eineList
Referenz des darin definierten Objekts der inneren Klasse zurückArrays
, das ebenfalls aufgerufen wird,ArrayList
aber privat ist und nur erweitertAbstractList
. Dies bedeutet, dass das zurückgegebeneArrays.asList(ia)
Objekt ein anderes Klassenobjekt ist als das, von dem Sie es erhaltennew ArrayList<Integer>
.Sie können einige Operationen nicht für Zeile 2 verwenden, da sich die innere private Klasse darin befindet
Arrays
diese Methoden nicht bereitstellt.Schauen Sie sich diesen Link an und sehen Sie, was Sie mit der privaten inneren Klasse tun können: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/ Arrays.java # Arrays.ArrayList
Zeile 1 erstellt ein neues
ArrayList
Objekt, das Elemente aus dem kopiert, was Sie aus Zeile 2 erhalten. Sie können also tun, was Sie wollen, dajava.util.ArrayList
alle diese Methoden bereitgestellt werden.quelle
Zusammenfassung des Unterschieds -
Wenn eine Liste ohne Verwendung des neuen Operators Arrays.asList () erstellt wird, wird Wrapper zurückgegeben
1. Sie können einen Add / Update-Vorgang ausführen.
2. Die im ursprünglichen Array vorgenommenen Änderungen werden auch in List übernommen und umgekehrt.
quelle
Als Antwort auf einige Kommentare, die Fragen zum Verhalten von Arrays.asList () seit Java 8 stellen:
quelle