Como Converter uma List em Array em Java
Converta uma List Java em array usando toArray e abordagens baseadas em streams.
Uma List e um array armazenam os mesmos elementos, mas expõem APIs diferentes: uma List redimensiona e possui métodos ricos, enquanto um array tem tamanho fixo e é o que muitas APIs antigas ou de baixo nível esperam. Converter de um para o outro é uma tarefa de uma linha no Java moderno — a única escolha real é qual forma é mais legível e se você precisa de um array de objetos ou de um primitivo. Esta página aborda a sobrecarga tipada de toArray, a referência de construtor do Java 11+, o caminho por stream para arrays primitivos e as armadilhas do toArray() sem argumentos.
A forma idiomática: toArray com um array tipado
List.toArray(T[]) retorna um array fortemente tipado. Passe um array de comprimento zero do tipo do elemento e deixe o JDK dimensionar o resultado para você:
List<String> names = List.of("Ann", "Bob", "Cy");
String[] arr = names.toArray(new String[0]);O argumento new String[0] carrega o tipo (String[]), não um buffer pré-dimensionado. Em JVMs modernas, a forma com array vazio é a recomendada — ela é tão rápida quanto um array perfeitamente dimensionado e evita o erro em que um array menor do que o necessário é realocado e um maior deixa nulls no final. Use isso sempre que precisar de um array de tipo Object como String[], Integer[] ou sua própria classe.
A forma do Java 11+: referência de construtor de array
Desde o Java 11, você pode passar uma referência de construtor de array em vez de um array vazio literal. Ela diz exatamente o que significa — "crie um String[] para mim":
String[] arr = names.toArray(String[]::new);Isso compila para a mesma coisa que new String[0], mas é mais claro. Note que o toArray() sem argumentos é uma armadilha: ele sempre retorna Object[], nunca String[], então converter seu resultado para String[] lança ClassCastException em tempo de execução.
| Abordagem | Tipo de resultado | Observações |
|---|---|---|
list.toArray(new String[0]) | String[] | Recomendada para arrays de objetos |
list.toArray(String[]::new) | String[] | Java 11+, forma mais clara |
list.toArray() | Object[] | Perde o tipo do elemento; raramente o que você quer |
list.stream().mapToInt(...).toArray() | int[] | A única forma de obter um array primitivo |
Arrays primitivos passam por um stream
toArray só pode produzir arrays de objetos. Uma List<Integer> não pode se tornar um int[] diretamente — o autoboxing não se estende a arrays. Use um stream para desempacotar cada elemento:
List<Integer> nums = List.of(10, 20, 30);
int[] prim = nums.stream().mapToInt(Integer::intValue).toArray();O mesmo padrão fornece long[] (mapToLong) e double[] (mapToDouble). Não existe atalho no JDK para arrays primitivos, portanto o stream é o caminho idiomático.
Um exemplo completo
Este programa executa todas as abordagens lado a lado, imprime o tipo em tempo de execução que o toArray sem argumentos realmente retorna e comprova que o array resultante é uma cópia independente — editá-lo não altera a lista original.
O que extrair da execução:
toArray(new String[0])etoArray(String[]::new)imprimem[Ann, Bob, Cy]— eles são duas formas de escrever a mesma conversão tipada, e você pode usar aquela que for mais legível em seu código.- O
toArray()sem argumentos informa seu tipo em tempo de execução comoObject[], nãoString[]— prova concreta de que ele apaga o tipo do elemento e por que você deve evitar converter seu resultado. - A
List<Integer>se torna umint[]real somente apósmapToInt; o[10, 20, 30]impresso é um array primitivo, não umInteger[], portanto nenhum boxing sobrevive. Arrays.stream(prim).sum()imprime60, confirmando que o resultado é um array primitivo utilizável que você pode passar diretamente para operações de stream numéricas.- Após
a1[0] = "ZZ", o array imprime[ZZ, Bob, Cy]enquanto a lista ainda imprime[Ann, Bob, Cy]—toArrayretorna uma cópia independente, portanto alterações no array nunca se propagam de volta para a lista de origem.