Copiar una lista a otra lista en Java

1. Información general

En este tutorial rápido, mostraremos diferentes formas de copiar una Lista a otra Lista y un error común producido en el proceso.

Para obtener una introducción al uso de las colecciones , consulte este artículo aquí.

2. Constructor

Una forma sencilla de copiar una lista es utilizando el constructor que toma una colección como argumento:

List copy = new ArrayList(list);

Debido al hecho de que estamos copiando la referencia aquí y no clonando los objetos, cada enmienda realizada en un elemento afectará a ambas listas.

Por esa razón, usar el constructor es bueno para copiar objetos inmutables:

List copy = new ArrayList(list);

Integer es una clase inmutable, su valor se establece cuando se crea la instancia y nunca puede cambiar.

Por lo tanto, una referencia de entero puede ser compartida por múltiples listas e hilos y no hay forma de que nadie pueda cambiar su valor.

3. Lista de ConcurrentAccessException

Un problema común al trabajar con listas es la ConcurrentAccessException . Esto podría significar que estamos modificando la lista mientras intentamos copiarla, probablemente en otro hilo.

Para solucionar este problema tenemos que:

  • Utilice una colección diseñada para acceso concurrente
  • Bloquear la colección de forma adecuada para iterar sobre ella
  • Encuentre una manera de evitar la necesidad de copiar la colección original

Teniendo en cuenta nuestro último enfoque, no es seguro para subprocesos. Entonces, si queremos resolver nuestro problema con la primera opción, es posible que deseemos usar CopyOnWriteArrayList , en el que todas las operaciones mutativas se implementan haciendo una copia nueva de la matriz subyacente.

Para obtener más información, consulte este artículo.

En caso de que queramos bloquear la colección , es posible usar una primitiva de bloqueo para serializar el acceso de lectura / escritura, como ReentrantReadWriteLock .

4. AddAll

Otro enfoque para copiar elementos es usar el método addAll :

List copy = new ArrayList(); copy.addAll(list);

Es importante tener en cuenta al usar este método que, al igual que con el constructor, el contenido de ambas listas hará referencia a los mismos objetos.

5. Colecciones.copia

La clase Colecciones consta exclusivamente de métodos estáticos que operan o devuelven colecciones.

Uno de ellos es la copia , que necesita una lista de fuentes y una lista de destinos al menos tan larga como la fuente.

Mantendrá el índice de cada elemento copiado en la lista de destinos como el original:

List source = Arrays.asList(1,2,3); List dest = Arrays.asList(4,5,6); Collections.copy(dest, source);

En el ejemplo anterior, todos los elementos anteriores de la lista de destinos se sobrescribieron porque ambas listas tienen el mismo tamaño.

En caso de que el tamaño de la lista de destinos sea mayor que el de la fuente:

List source = Arrays.asList(1, 2, 3); List dest = Arrays.asList(5, 6, 7, 8, 9, 10); Collections.copy(dest, source);

Solo se sobrescribieron los tres primeros elementos, mientras que el resto de los elementos de la lista se conservan.

6. Usando Java 8

Esta versión de Java abre nuestras posibilidades al agregar nuevas herramientas. El que exploraremos en los siguientes ejemplos es Stream :

List copy = list.stream() .collect(Collectors.toList());

Las principales ventajas de esta forma son la posibilidad de utilizar skip y filtros. En el siguiente ejemplo vamos a omitir el primer elemento:

List copy = list.stream() .skip(1) .collect(Collectors.toList());

También es posible filtrar por la longitud de la Cadena o comparando un atributo de nuestros objetos:

List copy = list.stream() .filter(s -> s.length() > 10) .collect(Collectors.toList());
List flowers = list.stream() .filter(f -> f.getPetals() > 6) .collect(Collectors.toList());

Es probable que queramos trabajar de forma segura para nulos:

List flowers = Optional.ofNullable(list) .map(List::stream)   .orElseGet(Stream::empty)   .collect(Collectors.toList());

Y omita un elemento usando esta forma también:

List flowers = Optional.ofNullable(list)   .map(List::stream).orElseGet(Stream::empty)   .skip(1)   .collect(Collectors.toList());

7. Usando Java 10

Finalmente, una de las últimas versiones de Java nos permite crear una Lista inmutable que contiene los elementos de la Colección dada :

List copy = List.copyOf(list);
Las únicas condiciones son que la colección dada no debe ser nula y no debe contener ningún elemento nulo.

8. Conclusión

En este artículo, hemos explorado diferentes formas de copiar una Lista a otra Lista con diferentes versiones de Java y un error común producido en el proceso. Como siempre, los ejemplos de código se pueden encontrar en GitHub aquí y aquí.