200 votes

Quelle est la différence entre List.of et Arrays.asList ?

Java 9 a introduit une nouvelle méthode 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 ? C'est-à-dire, quelle est la différence entre ceci :

Arrays.asList(1, 2, 3);

et ceci :

List.of(1, 2, 3);

303voto

orionll Points 1045

Arrays.asList retourne une liste mutable alors que la liste retournée par List.of est immuable :

List<Integer> list = Arrays.asList(1, 2, null);
list.set(1, 10); // OK

List<Integer> list = List.of(1, 2, 3);
list.set(1, 10); // Fails with UnsupportedOperationException

Arrays.asList autorise les éléments nuls tandis que List.of ne le fait pas :

List<Integer> list = Arrays.asList(1, 2, null); // OK
List<Integer> list = List.of(1, 2, null); // Fails with NullPointerException

contains se comporte différemment avec les valeurs nulles :

List<Integer> list = Arrays.asList(1, 2, 3);
list.contains(null); // Returns false

List<Integer> list = List.of(1, 2, 3);
list.contains(null); // Fails with NullPointerException

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. Pour List.of ce n'est pas vrai :

Integer[] array = {1,2,3};
List<Integer> list = Arrays.asList(array);
array[1] = 10;
System.out.println(list); // Prints [1, 10, 3]

Integer[] array = {1,2,3};
List<Integer> list = List.of(array);
array[1] = 10;
System.out.println(list); // Prints [1, 2, 3]

55voto

user1803551 Points 6057

Les différences entre Arrays.asList et List.of

Voir le JavaDocs et ceci parler de Stuart Marks (ou des versions précédentes).

Je vais utiliser les éléments suivants 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-modifiabilité)

Toute tentative de structurellement changement List.of se traduira par un UnsupportedOperationException . Cela comprend des opérations telles que ajouter , set et supprimer . Vous pouvez toutefois modifier le contenu des objets de la liste (si les objets ne sont pas immuables), la liste n'est donc pas "totalement immuable".

C'est le même sort pour les listes non modifiables créées avec Collections.unmodifiableList . Seule cette liste est une voir 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 les 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, le changement du tableau de support (si vous le détenez) modifiera 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.

Hostilité nulle

List.of et toute collection depuis Java 1.5 n'autorisent pas null comme un élément. Tenter de passer null en tant qu'élément ou même en tant que recherche donnera lieu à une NullPointerException .

Depuis Arrays.asList est une collection de la 1.2 (le cadre des collections), elle permet de null s.

listOf.contains(null);  // NullPointerException
unmodif.contains(null); // allowed
asList.contains(null);  // allowed

Forme sérialisée

Depuis List.of a été introduit 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 du JDK (pas de compatibilité binaire ). Toutefois, vous pouvez effectuer des opérations de sérialisation 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 retourné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 ) s'ils contiennent les mêmes éléments dans le même ordre, indépendamment de la façon dont ils ont été créés ou des opérations qu'ils supportent.

asList.equals(listOf); // true i.f.f. same elements in same order

Mise en œuvre (attention : les détails peuvent changer au fil des versions)

Si le nombre d'éléments dans la liste de List.of est égal ou inférieur à 2, 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 façon similaire à Arrays.asList .

Efficacité du temps et de l'espace

Le site List.of Les implémentations basées sur les champs (taille<2) sont légèrement plus rapides pour certaines opérations. À titre d'exemple, size() peut retourner une constante sans récupérer la longueur du tableau, et contains(E e) ne nécessite pas de surcharge d'itération.

Construction d'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 celui 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 économisez le UnmodifiableList l'emballage plus quelques centimes. Au final, les économies réalisées dans le HashSet équivalent sont plus convaincants.


Temps de conclusion : utilisation List.of quand vous voulez une liste qui ne change pas et Arrays.asList lorsque vous voulez une liste qui peut changer (comme indiqué ci-dessus).

25voto

Mohit Tyagi Points 1684

Résumons les différences entre Liste.de et Arrays.asList

  1. List.of peut être utilisé au mieux lorsque l'ensemble des données est moins important et inchangé, alors que Arrays.asList peut être utilisé au mieux dans le cas d'un ensemble de données volumineux et dynamique.

  2. List.of prend très peu d'espace de surcharge parce qu'il a une implémentation basée sur les champs et consomme moins d'espace de tas, à la fois en termes de surcharge fixe et sur une base par élément. alors que Arrays.asList prend plus d'espace de surcharge parce que pendant l'initialisation, il crée plus d'objets dans le tas.

  3. Collection retournée par List.of est immuable et donc sans risque pour les threads, alors que la collection retournée par Arrays.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).

  4. List.of ne permet pas null éléments tandis que Arrays.asList permet à null éléments.

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