Existe-t-il une alternative immuable aux tableaux primitifs en Java? Créer un tableau primitif final
n'empêche pas en fait de faire quelque chose comme
final int[] array = new int[] {0, 1, 2, 3};
array[0] = 42;
Je veux que les éléments du tableau soient inchangeables.
int[]
etnew int[]
est BEAUCOUP plus facile à taper queList<Integer>
etnew ArrayList<Integer>
? XDRéponses:
Pas avec les tableaux primitifs. Vous devrez utiliser une liste ou une autre structure de données:
la source
Arrays.asList
n'est pas non modifiable. docs.oracle.com/javase/7/docs/api/java/util/… "Renvoie une liste de taille fixe soutenue par le tableau spécifié. (Modifications apportées à la liste renvoyée" écrivez "sur le tableau.)"Arrays.asList()
effet non modifiable dans le sens où vous ne pouvez pas ou des éléments du retourné (à ne pas confondre avec ) - ces opérations ne sont tout simplement pas implémentées. Peut-être que @mauhiz essaie de dire ça? Mais bien sûr, vous pouvez modifier les éléments existants avec , donc certainement pas unmofiable , QED a ajouté le commentaire juste pour souligner la différence entre le résultat de et normaladd
remove
java.util.Arrays.ArrayList
java.util.ArrayList
List<> aslist = Arrays.asList(...); aslist.set(index, element)
java.util.Arrays.ArrayList
asList
ArrayList
Ma recommandation est de ne pas utiliser un tableau ou un
unmodifiableList
mais d'utiliser goyave de ImmutableList , qui existe à cet effet.la source
Collections.unmodifiableList
suffisant pour rendre une liste immuable?Comme d'autres l'ont noté, vous ne pouvez pas avoir de tableaux immuables en Java.
Si vous avez absolument besoin d'une méthode qui renvoie un tableau qui n'influence pas le tableau d'origine, vous devez cloner le tableau à chaque fois:
Évidemment, cela coûte assez cher (car vous créerez une copie complète à chaque fois que vous appelez le getter), mais si vous ne pouvez pas changer l'interface (pour utiliser un
List
par exemple) et que vous ne pouvez pas risquer que le client change vos données internes, alors cela peut être nécessaire.Cette technique s'appelle faire une copie défensive.
la source
clone()
ouArrays.copy()
ici?Il existe une façon de créer un tableau immuable en Java:
Les tableaux avec 0 élément (évidemment) ne peuvent pas être mutés.
Cela peut en fait être utile si vous utilisez la
List.toArray
méthode pour convertir unList
en tableau. Puisque même un tableau vide prend de la mémoire, vous pouvez enregistrer cette allocation de mémoire en créant un tableau vide constant et en le passant toujours à latoArray
méthode. Cette méthode allouera un nouveau tableau si le tableau que vous passez n'a pas assez d'espace, mais si c'est le cas (la liste est vide), il renverra le tableau que vous avez passé, vous permettant de réutiliser ce tableau à chaque fois que vous appeleztoArray
un videList
.la source
Une autre réponse
la source
A partir de Java 9 vous pouvez utiliser
List.of(...)
, JavaDoc .Cette méthode retourne un immuable
List
et est très efficace.la source
Si vous avez besoin (pour des raisons de performances ou pour économiser de la mémoire) natif 'int' au lieu de 'java.lang.Integer', alors vous devrez probablement écrire votre propre classe wrapper. Il existe diverses implémentations d'IntArray sur le net, mais aucune (j'ai trouvé) n'était immuable: Koders IntArray , Lucene IntArray . Il y en a probablement d'autres.
la source
Depuis Guava 22, à partir de package,
com.google.common.primitives
vous pouvez utiliser trois nouvelles classes, qui ont une empreinte mémoire inférieure àImmutableList
.Ils ont également un constructeur. Exemple:
ou, si la taille est connue au moment de la compilation:
C'est une autre façon d'obtenir une vue immuable d'un tableau pour les primitives Java.
la source
Non, ce n'est pas possible. Cependant, on pourrait faire quelque chose comme ceci:
Cela nécessite l'utilisation de wrappers, et c'est une liste, pas un tableau, mais c'est le plus proche que vous obtiendrez.
la source
valueOf()
s, l'auto-box s'en chargera. AussiArrays.asList(0, 2, 3, 4)
serait beaucoup plus concis.valueOf()
est d'utiliser le cache d'objets Integer interne pour réduire la consommation / le recyclage de la mémoire.int
en unInteger
cependant; il suffit de faire attention à l'inverse.Dans certaines situations, il sera plus léger d'utiliser cette méthode statique de la bibliothèque Google Guava:
List<Integer> Ints.asList(int... backingArray)
Exemples:
List<Integer> x1 = Ints.asList(0, 1, 2, 3)
List<Integer> x1 = Ints.asList(new int[] { 0, 1, 2, 3})
la source
Si vous voulez éviter à la fois la mutabilité et la boxe, il n'y a aucun moyen de sortir de la boîte. Mais vous pouvez créer une classe qui contient un tableau primitif et fournit un accès en lecture seule aux éléments via des méthodes.
la source
La méthode of (E ... elements) en Java9 peut être utilisée pour créer une liste immuable en utilisant juste une ligne:
La méthode ci-dessus renvoie une liste immuable contenant un nombre arbitraire d'éléments. Et ajouter n'importe quel entier à cette liste entraînerait une
java.lang.UnsupportedOperationException
exception. Cette méthode accepte également un seul tableau comme argument.la source
Bien qu'il soit vrai que cela
Collections.unmodifiableList()
fonctionne, vous pouvez parfois avoir une grande bibliothèque avec des méthodes déjà définies pour renvoyer des tableaux (par exempleString[]
). Pour éviter de les casser, vous pouvez en fait définir des tableaux auxiliaires qui stockeront les valeurs:Tester:
Pas parfait, mais au moins vous avez des "pseudo tableaux immuables" (du point de vue de la classe) et cela ne cassera pas le code associé.
la source
Eh bien .. les tableaux sont utiles pour passer en tant que constantes (si elles l'étaient) en tant que paramètres de variantes.
la source
int[]
, l'appelant peut bien supposer qu'il peut faire ce qu'il veut avec ce tableau sans affecter les composants internes de l'API.