Come convertire una List in un array in Java
Converti una List Java in un array usando toArray e approcci basati sugli stream.
Una List e un array contengono gli stessi elementi ma espongono API diverse: una List si ridimensiona e offre metodi avanzati, mentre un array ha lunghezza fissa ed è ciò che molte API di basso livello o legacy si aspettano. La conversione da uno all'altro è un'operazione su una sola riga nel Java moderno — l'unica vera scelta riguarda quale forma risulta più leggibile e se hai bisogno di un array di oggetti o di uno primitivo. Questa pagina tratta l'overload tipizzato di toArray, il riferimento al costruttore introdotto in Java 11+, il percorso tramite stream per gli array primitivi e le insidie del toArray() senza argomenti.
Il modo idiomatico: toArray con un array tipizzato
List.toArray(T[]) restituisce un array fortemente tipizzato. Passa un array di lunghezza zero del tipo dell'elemento e lascia che il JDK determini le dimensioni del risultato:
List<String> names = List.of("Ann", "Bob", "Cy");
String[] arr = names.toArray(new String[0]);L'argomento new String[0] trasporta il tipo (String[]), non un buffer pre-dimensionato. Sulle JVM moderne la forma con array vuoto è quella raccomandata — è veloce quanto un array perfettamente dimensionato ed evita il bug in cui un array troppo piccolo viene riallocato e uno troppo grande lascia null in coda. Usala ogni volta che hai bisogno di un array di tipo oggetto come String[], Integer[] o una tua classe personalizzata.
La forma Java 11+: un riferimento al costruttore di array
Da Java 11 puoi passare un riferimento al costruttore di array invece di un array vuoto letterale. Dice esattamente ciò che intende — "dammi un String[]":
String[] arr = names.toArray(String[]::new);Questo si compila nella stessa cosa di new String[0] ma si legge in modo più chiaro. Nota che il toArray() senza argomenti è una trappola: restituisce sempre Object[], mai String[], quindi eseguire il cast del suo risultato a String[] lancia ClassCastException a runtime.
| Approccio | Tipo risultante | Note |
|---|---|---|
list.toArray(new String[0]) | String[] | Raccomandato per array di oggetti |
list.toArray(String[]::new) | String[] | Java 11+, forma più chiara |
list.toArray() | Object[] | Perde il tipo dell'elemento; raramente è ciò che si vuole |
list.stream().mapToInt(...).toArray() | int[] | L'unico modo per ottenere un array primitivo |
Gli array primitivi passano attraverso uno stream
toArray può produrre solo array di oggetti. Una List<Integer> non può diventare direttamente un int[] — l'autoboxing non si estende agli array. Usa uno stream per estrarre il valore primitivo da ogni elemento:
List<Integer> nums = List.of(10, 20, 30);
int[] prim = nums.stream().mapToInt(Integer::intValue).toArray();Lo stesso pattern ti dà long[] (mapToLong) e double[] (mapToDouble). Non esiste una scorciatoia nel JDK per gli array primitivi, quindi lo stream è la via idiomatica.
Un esempio pratico
Questo programma esegue ogni approccio fianco a fianco, stampa il tipo runtime che toArray senza argomenti restituisce effettivamente e dimostra che l'array risultante è una copia indipendente — modificarlo non tocca la lista originale.
Cosa ricavare dall'esecuzione:
toArray(new String[0])etoArray(String[]::new)stampano entrambi[Ann, Bob, Cy]— sono due modi di scrivere la stessa conversione tipizzata, e puoi usare quello che si legge meglio nel tuo codebase.- Il
toArray()senza argomenti riporta il suo tipo runtime comeObject[], nonString[]— prova concreta che cancella il tipo dell'elemento e che dovresti evitare di eseguire il cast del suo risultato. - La
List<Integer>diventa un veroint[]solo dopomapToInt; il[10, 20, 30]stampato è un array primitivo, non unInteger[], quindi nessun boxing sopravvive. Arrays.stream(prim).sum()stampa60, confermando che il risultato è un array primitivo utilizzabile che puoi passare direttamente alle operazioni sugli stream numerici.- Dopo
a1[0] = "ZZ"l'array stampa[ZZ, Bob, Cy]mentre la lista stampa ancora[Ann, Bob, Cy]—toArrayrestituisce una copia indipendente, quindi le modifiche all'array non si propagano mai alla lista sorgente.