"Bug" no String.split() - Java ***Ler observação no final do post
Autor: Welder | Publicado: 2011-06-01T06:41:00-07:00

Esta postagem é uma curiosidade a respeito do método public String[] split(String regex) da classe java.lang.String do Java.
Inicialmente vou fazer uma pequena ilustração de como funciona o método split() pra quem não conhece, pois é um método extremamente útil, tanto que não está presente só no Java, mas também, em várias outras linguagens de programação.
A ação executada pelo split é tão simples quanto poderosa, dada uma String que possui vários campos separados por um delimitador, por exemplo, "banana;maçã;goiaba;manga" temos uma String com vários nomes de frutas separados pelo delimitador ";" (ponto e vírgula). Imagine então que exista a necessidade de "quebrar" essa String em várias outras Strings cada uma contendo o nome de uma fruta, teríamos então {"banana", "maçã", "goiaba", "manga"}. É exatamente nesse ponto que entra o String.split() ele executa essa ação de uma maneira bastante simples:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (...)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Inicialmente temos a String que deve ser "quebrada".&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String valores = "banana;maçã;goiaba;manga";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Então invocamos o split para que execute a ação.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] resultado = valores.split(";");&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (...)
Observe que o delimitador (neste caso ";") é passado como parâmetro para o método split(). Repare também que o split() retorna um array de Strings, contendo exatamente o resultado pretendido que é um array com as 4 Strings em cada campo.

Bom, após essa explicação rápida sobre o funcionamento do String.split(), podemos ilustraro ponto que é objetivo principal dessa postagem. O split() possui um pequeno "bug", talvez seja até um bug proposital, mas o fato é que pode causar algumas dores de cabeça na sua utilização.
Caso a String que contenha todos os campos a serem separados termine com a repetição do delimitador várias vezes, por exemplo, "banana;mação;goiaba;uva;;;;;" o split ignora a parte final gerando então um array contendo somente 4 Strings. A princípio isso pode até parecer uma coisa boa, mas imagine que exista a necessidade de validar a quantidade de colunas informadas por um usuário em um arquivo e que seja importante contar cada campo entre o delimitador, mesmo que esteja em branco como uma coluna vazia, ou seja, a String citada como exemplo deveria gerar um array com 8 Strings sendo que as 4 últimas seriam vazias. Nessa hipótese o split() não funcionaria corretamente, por isso considero que em determinados casos isso pode ser considerado um bug do método.
Como todo problema deve possuir uma solução, apresentarei aqui uma POG (Programação Orientada a Gambiarras) que utilizei para resolver esse problema, quando passei por ele.
Analisando melhor o split() percebi que caso a String que contenha os campos separados tenha uma sequência de delimitadores no meio da String, por exemplo, "maçã;banana;;;;;;goiaba;uva", o array gerado considera os campos vazios como parte do array gerado, ou seja, cada ";;" gera uma String vazia no array.
Deste modo, a solução caso a sequência de delimitadores seja no final da String, a solução que eu encontrei foi transformar esse final em meio. Como assim? Nada melhor do que o código para dizer o que ele mesmo faz:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (...)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String valores = "maçã;banana;goiaba;uva;;;;;"
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Basta concatenar qualquer coisa à String com os valores antes de&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //chamar o split:
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; valores += "qualquercoisa";
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //pronto! o split irá retornar o array de string com os campos vazios:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String[] resultado = valores.split(";");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (...)
Vale observar que no array de String resultado, o último elemento deverá ser desprezado, nesse caso seria a String "qualquercoisa".
Então, explicado o "bug" e uma solução alternativa aqui termina mais uma portagem do mundo da programação Java.

*** Observação: Um leitor anônimo alertou que existe uma solução alternativa para o problema destacado nesta postagem, tornando o tratamento dado neste post uma verdadeira GAMBIARRA. Quem tiver com o mesmo problema favor olhar os comentários.