Arrays.asList () vs Collections.singletonList ()

138

Y a-t-il un avantage (ou une grande différence) à utiliser Arrays.asList (quelque chose) sur Collections.singletonList (quelque chose) pour créer une liste contenant un élément? Ce dernier rend également la liste retournée immuable.

Howard Grimberg
la source
8
Vous pouvez également jeter des goyaves ImmutableList.of()et Lists.newArrayList()dans le mélange.
biziclop
En dehors de cela, j'ai eu des problèmes de Collections.singletonList () lorsqu'une méthode renvoie une liste qui est ultérieurement modifiée en aval.
Howard Grimberg
1
Java 10 a une véritable liste immuable: stackoverflow.com/a/52536126/1216775
akhil_mittal

Réponses:

207

Collections.singletonList(something)est immuable alors qu'il Arrays.asList(something)s'agit d'une Listreprésentation de taille fixe d'un tableau où la liste et le tableau sont joints dans le tas.

Arrays.asList(something)autorise les modifications non structurelles qui y sont apportées, qui sont reflétées à la fois dans la liste et dans le tableau joint. Il lance UnsupportedOperationExceptionpour ajouter, supprimer des éléments bien que vous puissiez définir un élément pour un index particulier.

Toute modification apportée à la liste renvoyée par Collections.singletonList(something)entraînera un UnsupportedOperationException.

De plus, la capacité de la liste renvoyée par Collections.singletonList(something)sera toujours de 1, contrairement à celle Arrays.asList(something)dont la capacité sera la taille de la baie sauvegardée.

Kumar Abhinav
la source
63

J'ajouterais simplement que la liste singleton n'est pas soutenue par un tableau et a juste une référence à cet élément. Vraisemblablement, cela prendrait moins de mémoire et pourrait être important en fonction du nombre de listes que vous souhaitez créer.

apprenti
la source
Un lien ou un code pour sauvegarder ce point d'efficacité de la mémoire? J'ai ce Arrays.asList (ONLY_ONE_OBJECT) largement écrit sur une base de code et j'aimerais savoir si le remplacement par Collections.singletonList () conduit à l'efficacité de la mémoire?
Rahul Saini
Arrays.asList fait référence à un tableau (évidemment): hg.openjdk.java.net/jdk8u/jdk8u/jdk/file/be44bff34df4/src/share / ... Collections.singletonList: hg.openjdk.java.net/jdk8u/jdk8u/jdk / file / be44bff34df4 / src / share /…
Benjamin
13

La méthode Arrays.asListrenvoie une liste de taille fixe soutenue par le tableau spécifié. La méthode renvoie une instance ArrayListdont est une classe statique imbriquée privée s'étendant AbstractListet non java.util.ArrayList. Cette classe statique fournit la mise en œuvre de quelques méthodes , par exemple , set, indexOf, forEach, replaceAlletc. , mais quand nous invoquons addil n'a pas la mise en œuvre de sa propre méthode un peu de AbstractListest invoquée qui jette java.lang.UnsupportedOperationException.

Le Collections.singletonListrenvoie une liste immuable contenant uniquement l'objet spécifié et il est également sérialisable.

Par ailleurs, pour les listes immuables, nous utilisons généralement Collections.unmodifiableListce qui renvoie une vue non modifiable de la liste spécifiée.

List<String> srcList = Arrays.asList("Apple", "Mango", "Banana");
var fruits = new ArrayList<>(srcList);
var unmodifiableList = Collections.unmodifiableList(fruits);     
fruits.set(0, "Apricot");
var modFruit = unmodifiableList.get(0);
System.out.println(modFruit); // prints Apricot

Une collection de vues non modifiable est une collection qui n'est pas modifiable et qui est également une vue sur une collection de support. Notez que des modifications de la collection de sauvegarde peuvent encore être possibles et, si elles se produisent, elles sont visibles via la vue non modifiable.

Nous pouvons avoir une véritable liste immuable dans Java 10 et versions ultérieures. Il existe deux façons d'obtenir une liste vraiment non modifiable :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Si l'une de ces deux variables est utilisée, la valeur sera toujours "Apple" et non "Apricot".

Selon la doc de Java 10 :

Les méthodes de fabrique statique List.ofet List.copyOffournissent un moyen pratique de créer des listes non modifiables. Les instances List créées par ces méthodes ont les caractéristiques suivantes:

  1. Ils ne sont pas modifiables . Les éléments ne peuvent pas être ajoutés, supprimés ou remplacés. L'appel de n'importe quelle méthode de mutateur sur la liste provoquera toujours la UnsupportedOperationExceptionlevée. Cependant, si les éléments contenus sont eux-mêmes modifiables, cela peut entraîner la modification du contenu de la liste.
  2. Ils interdisent les éléments nuls. Les tentatives de création avec des éléments nuls aboutissent à NullPointerException.
  3. Ils sont sérialisables si tous les éléments sont sérialisables.
  4. L'ordre des éléments dans la liste est le même que celui des arguments fournis ou des éléments du tableau fourni.
  5. Ils le sont value-based. Les appelants ne doivent faire aucune hypothèse sur l'identité des instances renvoyées. Les usines sont libres de créer de nouvelles instances ou de réutiliser celles existantes. Par conséquent, les opérations sensibles à l'identité sur ces instances (égalité de référence (==), code de hachage d'identité et synchronisation) ne sont pas fiables et doivent être évitées.
  6. Ils sont sérialisés comme spécifié sur la page Formulaire sérialisé .
akhil_mittal
la source