171 votes

Tableau immuable en Java

Existe-t-il une alternative immuable aux tableaux primitifs en Java ? Création d'un tableau primitif final n'empêche pas réellement 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 immuables.

182voto

Jason S Points 58434

Pas avec les tableaux primitifs. Vous devrez utiliser une liste ou une autre structure de données :

List<Integer> items = Collections.unmodifiableList(Arrays.asList(0,1,2,3));

78voto

ColinD Points 48573

Je recommande de ne pas utiliser un tableau ou un unmodifiableList mais pour utiliser Goyave 's Liste immuable qui existe à cette fin.

ImmutableList<Integer> values = ImmutableList.of(0, 1, 2, 3);

22voto

Joachim Sauer Points 133411

Comme d'autres l'ont fait remarquer, il est impossible d'avoir des 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, alors vous devrez cloner le tableau à chaque fois :

public int[] getFooArray() {
  return fooArray == null ? null : fooArray.clone();
}

Évidemment, cette méthode est plutôt coûteuse (puisque vous créerez une copie complète à chaque fois que vous appellerez le getter), mais si vous ne pouvez pas modifier l'interface (pour utiliser un fichier List par exemple) et ne peut pas risquer que le client modifie vos internes, alors cela peut être nécessaire.

Cette technique s'appelle faire une copie défensive.

15voto

Brigham Points 6316

Il existe un moyen de rendre un tableau immuable en Java :

final String[] IMMUTABLE = new String[0];

Les tableaux comportant 0 élément (évidemment) ne peuvent pas être mutés.

Cela peut s'avérer pratique si vous utilisez la fonction List.toArray pour convertir un List à un tableau. Puisque même un tableau vide occupe un peu de mémoire, vous pouvez économiser cette allocation de mémoire en créant un tableau vide constant, et en le passant toujours à la fonction toArray méthode. Cette méthode allouera un nouveau tableau si le tableau que vous passez n'a pas assez de place, mais si c'est le cas (la liste est vide), elle retournera le tableau que vous avez passé, vous permettant de réutiliser ce tableau à chaque fois que vous appelez toArray sur un vide List .

final static String[] EMPTY_STRING_ARRAY = new String[0];

List<String> emptyList = new ArrayList<String>();
return emptyList.toArray(EMPTY_STRING_ARRAY); // returns EMPTY_STRING_ARRAY

6voto

aeracode Points 496

Une autre réponse

static class ImmutableArray<T> {
    final T[] array;

    private ImmutableArray(T[] a){
        array = Arrays.copyOf(a, a.length);
    }

    public static <T> ImmutableArray<T> from(T[] a){
        return new ImmutableArray<T>(a);
    }

    public T get(int index){
        return array[index];
    }
}

{
    final ImmutableArray<String> sample = ImmutableArray.from(new String[]{"a", "b", "c"});
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X