Arrays.asList () vs Collections.singletonList ()

138

¿Hay alguna ventaja (o mucha diferencia) en usar Arrays.asList (algo) sobre Collections.singletonList (algo) para hacer una lista que contenga un elemento? Esto último también hace que la lista devuelta sea inmutable.

Howard Grimberg
fuente
8
Puedes tirar guayabas ImmutableList.of()y también Lists.newArrayList()en la mezcla.
biziclop
Aparte de esto, he tenido que Collections.singletonList () causó problemas cuando un método devuelve una Lista que luego se modifica en sentido descendente.
Howard Grimberg
1
Java 10 tiene una verdadera lista inmutable: stackoverflow.com/a/52536126/1216775
akhil_mittal

Respuestas:

207

Collections.singletonList(something)es inmutable, mientras que Arrays.asList(something)es una Listrepresentación de tamaño fijo de una matriz donde la lista y la matriz se unen en el montón.

Arrays.asList(something)permite realizar cambios no estructurales , que se reflejan tanto en la Lista como en la matriz conjunta. Se lanza UnsupportedOperationExceptionpara agregar, eliminar elementos, aunque puede establecer un elemento para un índice particular.

Cualquier cambio realizado en la Lista devuelto por Collections.singletonList(something)resultará en UnsupportedOperationException.

Además, la capacidad de la Lista devuelta por Collections.singletonList(something)siempre será 1, a diferencia de Arrays.asList(something)cuya capacidad será el tamaño de la matriz respaldada.

Kumar Abhinav
fuente
63

Solo agregaría que la lista única no está respaldada por una matriz y solo tiene una referencia a ese elemento. Presumiblemente, tomaría menos memoria y puede ser significativo dependiendo de la cantidad de listas que desee crear.

aprendiz
fuente
¿Algún enlace o código para respaldar este punto de eficiencia de memoria? Tengo este Arrays.asList (ONLY_ONE_OBJECT) escrito ampliamente en una base de código y me gustaría saber si reemplazarlo con Collections.singletonList () conduce a la eficiencia de la memoria.
Rahul Saini el
Arrays.asList hace referencia a una matriz (obviamente): 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

El método Arrays.asListdevuelve una lista de tamaño fijo respaldada por la matriz especificada. El método devuelve una instancia de la ArrayListcual es una clase estática privada anidada que se extiende AbstractListy no java.util.ArrayList. Esta clase estática proporciona la implementación de algunos métodos, por ejemplo, set, indexOf, forEach, replaceAlletc., pero cuando invocamos addno tiene implementación propia, sino que AbstractListse invoca el método desde el que se lanza java.lang.UnsupportedOperationException.

El Collections.singletonListdevuelve una lista inmutable que contiene solo el objeto especificado y también es serializable.

En una nota al margen, para las listas inmutables generalmente utilizamos Collections.unmodifiableListque devuelve una vista no modificable de la lista especificada.

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

Una colección de vistas no modificables es una colección que no se puede modificar y también es una vista de una colección de respaldo. Tenga en cuenta que los cambios en la colección de respaldo aún podrían ser posibles, y si ocurren, son visibles a través de la vista no modificable.

Podemos tener una verdadera lista inmutable en Java 10 y versiones posteriores. Hay dos formas de obtener una lista verdaderamente inmodificable :

  1. var unmodifiableList = List.copyOf(srcList);
  2. var unmodifiableList = srcList.stream().collect(Collectors.toUnmodifiableList()); Si se usa alguna de estas dos variables, el valor seguirá siendo "Apple" y no "Apricot".

Según el documento de Java 10 :

Los métodos de fábrica List.ofy List.copyOfestáticos proporcionan una forma conveniente de crear listas no modificables. Las instancias de List creadas por estos métodos tienen las siguientes características:

  1. Son inmodificables . Los elementos no se pueden agregar, eliminar o reemplazar. Llamar a cualquier método mutador en la Lista siempre hará UnsupportedOperationExceptionque se arroje. Sin embargo, si los elementos contenidos son mutables, esto puede hacer que el contenido de la Lista parezca cambiar.
  2. No permiten elementos nulos. Los intentos de crearlos con elementos nulos resultan en NullPointerException.
  3. Son serializables si todos los elementos son serializables.
  4. El orden de los elementos en la lista es el mismo que el orden de los argumentos proporcionados, o de los elementos en la matriz proporcionada.
  5. Son value-based. Las personas que llaman no deben hacer suposiciones sobre la identidad de las instancias devueltas. Las fábricas son libres de crear nuevas instancias o reutilizar las existentes. Por lo tanto, las operaciones sensibles a la identidad en estas instancias (igualdad de referencia (==), código hash de identidad y sincronización) no son confiables y deben evitarse.
  6. Se serializan como se especifica en la página del formulario serializado .
akhil_mittal
fuente