Voir les JavaDocs et cet exposé de Stuart Marks (ou des versions précédentes de celui-ci).
J'utiliserai ce qui suit pour les exemples de code:
List<Integer> listOf = List.of(...);
List<Integer> asList = Arrays.asList(...);
List<Integer> unmodif = Collections.unmodifiableList(asList);
Immuabilité structurelle (Ou: non modifiable)
Toute tentative de changement structurelList.of
entraînera un UnsupportedOperationException
. Cela inclut des opérations telles que l' ajout , la définition et la suppression . Vous pouvez cependant modifier le contenu des objets de la liste (si les objets ne sont pas immuables), de sorte que la liste ne soit pas «complètement immuable».
C'est le même sort pour les listes non modifiables créées avec Collections.unmodifiableList
. Seule cette liste est une vue de la liste d'origine, elle peut donc changer si vous modifiez la liste d'origine.
Arrays.asList
n'est pas complètement immuable, il n'a pas de restriction sur set
.
listOf.set(1, "a"); // UnsupportedOperationException
unmodif.set(1, "a"); // UnsupportedOperationException
asList.set(1, "a"); // modified unmodif! unmodif is not truly unmodifiable
De même, changer le tableau de sauvegarde (si vous le maintenez) changera la liste.
L'immuabilité structurelle s'accompagne de nombreux effets secondaires liés au codage défensif, à la concurrence et à la sécurité qui dépassent le cadre de cette réponse.
Nulle hostilité
List.of
et toute collection depuis Java 1.5 ne permet pas null
en tant qu'élément. Tenter de passer null
en tant qu'élément ou même une recherche entraînera un fichier NullPointerException
.
Puisqu'il Arrays.asList
s'agit d'une collection de 1.2 (le Framework de collections), il autorise null
s.
listOf.contains(null); // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null); // allowed
Formulaire sérialisé
Depuis List.of
son introduction dans Java 9 et les listes créées par cette méthode ont leur propre forme sérialisée (binaire), elles ne peuvent pas être désérialisées sur les versions antérieures de JDK (pas de compatibilité binaire ). Cependant, vous pouvez dé / sérialiser avec JSON, par exemple.
Identité
Arrays.asList
appels internes new ArrayList
, ce qui garantit l'inégalité de référence.
List.of
dépend de la mise en œuvre interne. Les instances renvoyées peuvent avoir une égalité de référence, mais comme cela n'est pas garanti, vous ne pouvez pas vous y fier.
asList1 == asList2; // false
listOf1 == listOf2; // true or false
Il convient de mentionner que les listes sont égales (via List.equals
) si elles contiennent les mêmes éléments dans le même ordre, indépendamment de la façon dont elles ont été créées ou des opérations qu'elles prennent en charge.
asList.equals(listOf); // true i.f.f. same elements in same order
Mise en œuvre (avertissement: les détails peuvent changer au fil des versions)
Si le nombre d'éléments dans la liste de List.of
est de 2 ou moins, les éléments sont stockés dans des champs d'une classe spécialisée (interne). Un exemple est la liste qui stocke 2 éléments (source partielle):
static final class List2<E> extends AbstractImmutableList<E> {
private final E e0;
private final E e1;
List2(E e0, E e1) {
this.e0 = Objects.requireNonNull(e0);
this.e1 = Objects.requireNonNull(e1);
}
}
Sinon, ils sont stockés dans un tableau de la même manière que Arrays.asList
.
Efficacité temporelle et spatiale
Les List.of
implémentations basées sur le champ (taille <2) sont légèrement plus rapides sur certaines opérations. Par exemple, size()
peut renvoyer une constante sans récupérer la longueur du tableau et contains(E e)
ne nécessite pas de surcharge d'itération.
Construire une liste non modifiable via List.of
est également plus rapide. Comparez le constructeur ci-dessus avec 2 affectations de référence (et même celle pour un nombre arbitraire d'éléments) à
Collections.unmodifiableList(Arrays.asList(...));
ce qui crée 2 listes plus d'autres frais généraux. En termes d'espace, vous enregistrez l' UnmodifiableList
emballage plus quelques centimes. Au final, les économies en HashSet
équivalent sont plus convaincantes.
Temps de conclusion: à utiliser List.of
lorsque vous voulez une liste qui ne change pas et Arrays.asList
lorsque vous voulez une liste qui peut changer (comme indiqué ci-dessus).