Gibt es eine unveränderliche Alternative zu den primitiven Arrays in Java? Das Erstellen eines primitiven Arrays final
hindert einen nicht daran, so etwas zu tun
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
Ich möchte, dass die Elemente des Arrays unveränderlich sind.
int[]
undnew int[]
ist viel einfacher zu tippen alsList<Integer>
undnew ArrayList<Integer>
? XDAntworten:
Nicht mit primitiven Arrays. Sie müssen eine Liste oder eine andere Datenstruktur verwenden:
quelle
Arrays.asList
ist nicht unveränderbar. docs.oracle.com/javase/7/docs/api/java/util/… "Gibt eine Liste mit fester Größe zurück, die vom angegebenen Array unterstützt wird. (Änderungen an der zurückgegebenen Liste" durchschreiben "in das Array.)"Arrays.asList()
Tat nicht modifizierbar in dem Sinne, dass Sie nichtadd
oderremove
Elemente der zurückgegebenenjava.util.Arrays.ArrayList
( nicht zu verwechseln mitjava.util.ArrayList
) - diese Operationen sind einfach nicht implementiert. Vielleicht versucht @mauhiz das zu sagen? Aber natürlich können Sie vorhandene Elemente mit QED ändernList<> aslist = Arrays.asList(...); aslist.set(index, element)
, wasjava.util.Arrays.ArrayList
sicherlich nicht unerheblich ist. Der Kommentar wurde hinzugefügt , um den Unterschied zwischen dem Ergebnis vonasList
und normal hervorzuhebenArrayList
Meine Empfehlung ist , nicht um ein Array zu verwenden oder
unmodifiableList
aber zu verwenden Guava ‚s ImmutableList , die für diesen Zweck vorhanden ist .quelle
Collections.unmodifiableList
reicht dies aus, um eine Liste unveränderlich zu machen?Wie andere angemerkt haben, können Sie in Java keine unveränderlichen Arrays haben.
Wenn Sie unbedingt eine Methode benötigen, die ein Array zurückgibt, das das ursprüngliche Array nicht beeinflusst, müssen Sie das Array jedes Mal klonen:
Dies ist natürlich ziemlich teuer (da Sie jedes Mal, wenn Sie den Getter aufrufen, eine vollständige Kopie erstellen), aber wenn Sie die Schnittstelle nicht ändern können (
List
um beispielsweise eine zu verwenden) und nicht riskieren können, dass der Client Ihre Interna ändert, dann es kann notwendig sein.Diese Technik wird als Erstellen einer defensiven Kopie bezeichnet.
quelle
clone()
oderArrays.copy()
hier?Es gibt eine Möglichkeit, ein unveränderliches Array in Java zu erstellen:
Arrays mit 0 Elementen können (offensichtlich) nicht mutiert werden.
Dies kann tatsächlich nützlich sein, wenn Sie die
List.toArray
Methode zum Konvertieren von aList
in ein Array verwenden. Da selbst ein leeres Array Speicherplatz beansprucht, können Sie diese Speicherzuordnung speichern, indem Sie ein konstantes leeres Array erstellen und es immer an dietoArray
Methode übergeben. Diese Methode weist ein neues Array zu, wenn das übergebene Array nicht über genügend Speicherplatz verfügt. Wenn dies jedoch der Fall ist (die Liste ist leer), wird das übergebene Array zurückgegeben, sodass Sie dieses Array bei jedem AufruftoArray
eines Arrays wiederverwenden können leerList
.quelle
Noch eine Antwort
quelle
Ab Java 9 können Sie verwenden
List.of(...)
, JavaDoc .Diese Methode gibt eine unveränderliche zurück
List
und ist sehr effizient.quelle
Wenn Sie (aus Leistungsgründen oder um Speicherplatz zu sparen) natives 'int' anstelle von 'java.lang.Integer' benötigen, müssen Sie wahrscheinlich Ihre eigene Wrapper-Klasse schreiben. Es gibt verschiedene IntArray-Implementierungen im Netz, aber keine (ich fand) war unveränderlich: Koders IntArray , Lucene IntArray . Es gibt wahrscheinlich andere.
quelle
Seit Guava 22 können Sie ab Paket
com.google.common.primitives
drei neue Klassen verwenden, die im Vergleich zu weniger Speicherplatz habenImmutableList
.Sie haben auch einen Baumeister. Beispiel:
oder, wenn die Größe zur Kompilierungszeit bekannt ist:
Dies ist eine weitere Möglichkeit, eine unveränderliche Ansicht eines Arrays für Java-Grundelemente zu erhalten.
quelle
Nein das ist nicht möglich. Man könnte jedoch so etwas tun:
Dies erfordert die Verwendung von Wrappern und ist eine Liste, kein Array, aber die nächstgelegene, die Sie erhalten.
quelle
valueOf()
s schreiben , Autoboxing wird sich darum kümmern. WäreArrays.asList(0, 2, 3, 4)
auch viel prägnanter.valueOf()
besteht darin, den internen Integer- Objektcache zu verwenden, um den Speicherverbrauch / das Recycling zu reduzieren.int
in eineInteger
obwohl umwandelt ; muss nur umgekehrt vorsichtig sein.In einigen Situationen ist die Verwendung dieser statischen Methode aus der Google Guava-Bibliothek leichter:
List<Integer> Ints.asList(int... backingArray)
Beispiele:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
quelle
Wenn Sie sowohl Veränderlichkeit als auch Boxen vermeiden möchten, gibt es keinen Ausweg. Sie können jedoch eine Klasse erstellen, die ein primitives Array enthält und über Methoden einen schreibgeschützten Zugriff auf Elemente bietet.
quelle
Mit der Methode of (E ... elements) in Java9 kann eine unveränderliche Liste mit nur einer Zeile erstellt werden:
Die obige Methode gibt eine unveränderliche Liste zurück, die eine beliebige Anzahl von Elementen enthält. Das Hinzufügen einer Ganzzahl zu dieser Liste würde zu einer
java.lang.UnsupportedOperationException
Ausnahme führen. Diese Methode akzeptiert auch ein einzelnes Array als Argument.quelle
Es stimmt zwar, dass dies
Collections.unmodifiableList()
funktioniert, aber manchmal haben Sie eine große Bibliothek, in der bereits Methoden definiert sind, um Arrays zurückzugeben (zString[]
. B. ). Um zu verhindern, dass sie beschädigt werden, können Sie Hilfsarrays definieren, in denen die Werte gespeichert werden:Zu testen:
Nicht perfekt, aber zumindest haben Sie "pseudo-unveränderliche Arrays" (aus der Klassenperspektive) und dies wird den zugehörigen Code nicht beschädigen.
quelle
Nun ... Arrays sind nützlich, um sie als Konstanten (falls vorhanden) als Variantenparameter zu übergeben.
quelle
int[]
, kann der Aufrufer davon ausgehen, dass er mit diesem Array das tun kann, was er will, ohne die Interna der API zu beeinflussen.