Conversão de ArrayList<String> para String[]: 5 erros fatais de iniciante

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

ArrayList<String> para String[]: não se deixe enganar

\n\n

Olá, amigo! Se você está lendo isto, significa que já se deparou com a tarefa clássica — transformar um ArrayList<String> em um array comum String[]. Parece simples, não é? Você pega o método toArray(), chama e pronto. Mas não é bem assim! Java é uma linguagem traiçoeira, e até mesmo uma operação tão simples pode se tornar uma dor de cabeça se você não conhecer as armadilhas.

\n\n

No Stack Overflow, essa pergunta tem milhares de visualizações, e não é à toa. Reunimos os 5 principais erros que até mesmo desenvolvedores experientes cometem e mostraremos como evitá-los. Vamos lá!

\n\n

Por que simplesmente list.toArray() não funciona?

\n\n

Vamos direto ao ponto. Você tem uma lista:

\n\n
ArrayList<String> list = new ArrayList<>();\nlist.add("Java");\nlist.add("Python");\nlist.add("C++");
\n\n

Você quer obter um array de strings. O primeiro pensamento é chamar list.toArray(). Veja o que acontece:

\n\n
Object[] objectArray = list.toArray(); // Funciona, mas retorna Object[]\n// String[] stringArray = list.toArray(); // Erro de compilação!
\n\n

Erro nº 1: esquecer a conversão de tipos. O método toArray() sem argumentos retorna Object[], não String[]. O compilador não permitirá que você simplesmente atribua um Object[] a uma variável do tipo String[]. É necessário um cast explícito:

\n\n
String[] stringArray = (String[]) list.toArray(); // ClassCastException em tempo de execução!
\n\n

É aqui que a coisa fica interessante. O segundo erro é pensar que o cast vai resolver. Você receberá um ClassCastException, porque internamente o toArray() cria um array do tipo Object[], não String[]. O cast não altera o tipo do objeto — ele apenas diz ao compilador: "Confie em mim, é uma string". E o Java, em tempo de execução, verifica e lança a exceção.

\n\n

O caminho correto: toArray(new String[0])

\n\n

A maneira mais comum e correta é passar um array vazio do tipo desejado para o toArray():

\n\n
String[] stringArray = list.toArray(new String[0]);
\n\n

Por que isso funciona? Porque o método toArray(T[] a) é um método genérico. Ele recebe um array do tipo T e retorna um array do mesmo tipo. Se o array passado não for grande o suficiente, o método cria um novo array do tipo correto usando reflexão. Se o tamanho for adequado, ele o preenche.

\n\n

Erro nº 3: passar um array de tamanho incorreto. Alguns iniciantes escrevem:

\n\n
String[] stringArray = list.toArray(new String[list.size()]);
\n\n

Isso também funciona, mas vamos analisar o que é melhor. Quando passamos um array de tamanho list.size(), o método o preenche e o retorna. Se passarmos new String[0], um novo array é criado. Parece que estamos perdendo tempo criando um novo array, certo? Na verdade, a JVM otimiza a criação de um array vazio, e na maioria dos casos new String[0] é mais rápido do que new String[list.size()]. Por quê? Porque no segundo caso, o array é criado, depois preenchido com nulls e, em seguida, sobrescrito. Trabalho extra.

\n\n

JVM modernas (Java 8+) frequentemente otimizam new String[0] para uma constante, tornando-o mais rápido. Mas se você estiver trabalhando com Java 6 ou 7, a diferença pode ser perceptível. De qualquer forma, a melhor prática é usar new String[0], a menos que seja necessária performance ultra-alta. Para trechos de código críticos em velocidade, teste ambas as opções.

\n\n

A armadilha: sincronização e concorrência

\n\n

Erro nº 4: conversão em ambiente multithread sem sincronização. Imagine: você tem um ArrayL

Blogs

Book Recommendations