Copia un elenco in un altro elenco in Java

1. Panoramica

In questo rapido tutorial, mostreremo diversi modi per copiare un elenco in un altro elenco e un errore comune prodotto nel processo.

Per un'introduzione all'uso delle raccolte , fare riferimento a questo articolo qui.

2. Costruttore

Un modo semplice per copiare una lista è usare il costruttore che accetta una raccolta come argomento:

List copy = new ArrayList(list);

A causa del fatto che qui stiamo copiando il riferimento e non clonando gli oggetti, ogni modifica apportata a un elemento avrà effetto su entrambi gli elenchi.

Per questo motivo, utilizzare il costruttore è utile per copiare oggetti immutabili:

List copy = new ArrayList(list);

Integer è una classe immutabile, il suo valore viene impostato al momento della creazione dell'istanza e non può mai cambiare.

Un riferimento intero può quindi essere condiviso da più elenchi e thread e nessuno può modificarne il valore.

3. Elenca ConcurrentAccessException

Un problema comune nell'utilizzo degli elenchi è ConcurrentAccessException . Ciò potrebbe significare che stiamo modificando l'elenco mentre stiamo cercando di copiarlo, molto probabilmente in un altro thread.

Per risolvere questo problema dobbiamo:

  • Utilizzare un progettato per la raccolta di accesso simultaneo
  • Blocca la raccolta in modo appropriato per eseguire l'iterazione su di essa
  • Trova un modo per evitare di dover copiare la collezione originale

Considerando il nostro ultimo approccio, non è thread-safe. Quindi, se vogliamo risolvere il nostro problema con la prima opzione, potremmo voler usare CopyOnWriteArrayList , in cui tutte le operazioni mutative vengono implementate facendo una nuova copia dell'array sottostante.

Per ulteriori informazioni, fare riferimento a questo articolo.

Nel caso in cui si desideri bloccare la Collection , è possibile utilizzare una primitiva di blocco per serializzare l'accesso in lettura / scrittura, come ReentrantReadWriteLock .

4. Aggiungi tutto

Un altro approccio per copiare gli elementi consiste nell'usare il metodo addAll :

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

È importante tenere a mente ogni volta che si utilizza questo metodo che, come con il costruttore, il contenuto di entrambi gli elenchi farà riferimento agli stessi oggetti.

5. Collections.copy

La classe Collections è costituita esclusivamente da metodi statici che operano o restituiscono raccolte.

Uno di questi è la copia , che necessita di un elenco di origine e di un elenco di destinazione lunghi almeno quanto l'origine.

Manterrà l'indice di ogni elemento copiato nell'elenco di destinazione come l'originale:

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

Nell'esempio precedente, tutti gli elementi precedenti nell'elenco di destinazione sono stati sovrascritti perché entrambi gli elenchi hanno la stessa dimensione.

Nel caso in cui la dimensione dell'elenco di destinazione sia maggiore dell'origine:

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

Solo i primi tre elementi sono stati sovrascritti mentre il resto degli elementi nell'elenco vengono conservati.

6. Utilizzo di Java 8

Questa versione di Java apre le nostre possibilità aggiungendo nuovi strumenti. Quello che esploreremo nei prossimi esempi è Stream :

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

I principali vantaggi di questo metodo sono la possibilità di utilizzare salta e filtri. Nel prossimo esempio salteremo il primo elemento:

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

È possibile filtrare anche in base alla lunghezza della Stringa o confrontando un attributo dei nostri oggetti:

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

È probabile che vogliamo lavorare in modo null-safe:

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

E salta un elemento anche in questo modo:

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

7. Utilizzo di Java 10

Infine, una delle ultime versioni di Java ci permette di creare un List immutabile contenente gli elementi della data Collection:

List copy = List.copyOf(list);
Le uniche condizioni sono che la Collection data non deve essere nulla e non deve contenere elementi nulli.

8. Conclusione

In questo articolo, abbiamo esplorato diversi modi per copiare un elenco in un altro elenco con diverse versioni di Java e un errore comune prodotto nel processo. Come sempre, gli esempi di codice possono essere trovati su GitHub qui e qui.