Java 9 a introduit de nouvelles méthodes d'usine pour les listes List.of
:
List<String> strings = List.of("first", "second");
Quelle est la différence entre l'ancienne et la nouvelle option? Autrement dit, quelle est la différence entre ceci:
Arrays.asList(1, 2, 3);
et ça:
List.of(1, 2, 3);
Réponses:
Arrays.asList
renvoie une liste modifiable alors que la liste retournée parList.of
est immuable :Arrays.asList
autorise les éléments nuls alors queList.of
ne le fait pas:contains
se comporte différemment avec les valeurs nulles:Arrays.asList
renvoie une vue du tableau passé, de sorte que les modifications apportées au tableau seront également reflétées dans la liste. CarList.of
ce n'est pas vrai:la source
List.contains(Object o)
javadoc du 's : "Lance [...] NullPointerException - si l'élément spécifié est nul et que cette liste n'autorise pas les éléments nuls (facultatif)". Ou de la longue introduction de l'interface que peu de gens lisent: "Certaines implémentations de collection ont des restrictions sur les éléments qu'elles peuvent contenir"List.of
ne revenir unImmutableList
type de son nom réel est un détail de mise en œuvre non publiques. Si c'était public et que quelqu'un l'a rejouéList
, où était la différence? Où est la différence avecArrays.asList
, qui renvoie uneList
implémentation non publique , qui lève une exception lors de la tentativeadd
ouremove
, ou la liste renvoyée parCollections.unmodifiableList
laquelle ne permet aucune modification? Tout est question de contrats spécifiés dans l'List
interface. Les interfaces Collections avec des méthodes optionnelles étaient toujours impures POO depuis Java 1.2…Les différences entre
Arrays.asList
etList.of
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:
Immuabilité structurelle (Ou: non modifiable)
Toute tentative de changement structurel
List.of
entraînera unUnsupportedOperationException
. 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 surset
.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 pasnull
en tant qu'élément. Tenter de passernull
en tant qu'élément ou même une recherche entraînera un fichierNullPointerException
.Puisqu'il
Arrays.asList
s'agit d'une collection de 1.2 (le Framework de collections), il autorisenull
s.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 internesnew 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.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.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):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 etcontains(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) à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 enHashSet
équivalent sont plus convaincantes.Temps de conclusion: à utiliser
List.of
lorsque vous voulez une liste qui ne change pas etArrays.asList
lorsque vous voulez une liste qui peut changer (comme indiqué ci-dessus).la source
Arrays.asList
n'est pas entièrement modifiable.asList.add(1);
jette unUnsupportedOperationException
.List.of
temps que les gens voudront appelercontains
et ne pas être surpris par une NullPointerException.Résumons les différences entre List.of et Arrays.asList
List.of
peut être mieux utilisé lorsque l'ensemble de données est inférieur et inchangé, alors qu'ilArrays.asList
peut être utilisé au mieux dans le cas d'un ensemble de données volumineux et dynamique.List.of
prend très moins d'espace supplémentaire car il a une implémentation basée sur le terrain et consomme moins d'espace de tas, à la fois en termes de surcharge fixe et sur une base par élément. tandis queArrays.asList
prennent plus d'espace de surcharge car lors de l'initialisation, il crée plus d'objets dans le tas.La collection retournée par
List.of
est immuable et donc sécurisée pour les threads tandis que la collection retournée parArrays.asList
est mutable et non thread-safe. (Les instances de collection immuables consomment généralement beaucoup moins de mémoire que leurs homologues mutables.)List.of
ne permet pas null éléments toutArrays.asList
permet nuls éléments.la source
Arrays.asList
versusList.of
, étant donné que le premier n'est littéralement qu'un wrapper autour d'un tableau. Au moins l'implémentation d'OpenJDK semble avoir une surcharge extrêmement faible. En fait,List.of
il faudrait faire des copies de tout tableau passé, donc à moins que le tableau lui-même ne soit bientôt GC, il semblerait qu'ilList.of
ait une empreinte mémoire beaucoup plus grande.List.of(x)
etList.of(x, y)
sont plus efficaces car ils n'allouent pas du tout de tableauxList.of
méthodes ne sont pas obligées de renvoyer de nouvelles listes à chaque fois. Ces listes ont une identité non spécifiée, de sorte qu'une mise en cache, une déduplication ou une scalarisation peuvent être gérées au niveau de la JVM. Si ce n'est pas dans cette version, alors peut-être dans la suivante. C'est permis par le contrat. En revanche, celaArray.asList
dépend de l'identité du tableau que vous transmettez, car la liste résultante est une vue mutable sur le tableau, reflétant tout changement bidirectionnel.En dehors des réponses ci-dessus, il existe certaines opérations sur lesquelles les deux
List::of
etArrays::asList
diffèrent:En savoir plus sur les collections :: singletonList Vs. Liste de
la source