O método split() da classe String em Java é amplamente utilizado para dividir uma string em um array de substrings, baseando-se em um delimitador. Embora seu uso básico seja simples, o comportamento do seu parâmetro limit pode gerar nuances importantes. Vamos explorar suas variações e entender como ele afeta o resultado.
Compreendendo as Sobrecargas de split()
A forma mais comum de usar o método é com um único argumento:
public String[] split(String regex) {
return split(regex, 0);
}
Como podemos ver, esta é uma sobrecarga que invoca o método principal split(String regex, int limit), passando 0 como valor padrão para o parâmetro limit.
O método completo é onde toda a lógica reside:
public String[] split(String regex, int limit) {
// Tenta uma divisão rápida sem alocar um objeto Pattern
String[] fast = Pattern.fastSplit(regex, this, limit);
if (fast != null) {
return fast;
}
return Pattern.compile(regex).split(this, limit);
}
A chave para entender o comportamento de split() está no parâmetro limit. Ele define quantas vezes o padrão será aplicado e, consequentemente, influencia o comprimento do array resultante. Vamos analisar como diferentes valores de limit afetam a divisão.
limit = 0 (Comportamento Padrão)
Quando limit é zero, o método tenta dividir a string o máximo de vezes possível. A principal característica neste cenário é que quaisquer strings vazias resultantes no final do array são descartadas. Strings vazias no início ou no meio do array, no entanto, são mantidas.
Exemplo 1: Tratamento de Delimitador Final
Considere uma string com um delimitador no final, que teoricamente resultaria em uma string vazia ao final da divisão.
String dados = "maçã,banana,laranja,";
String[] partes = dados.split(",");
System.out.println("Elementos:");
for (String parte : partes) {
System.out.println(" - " + parte);
}
System.out.println("Comprimento do array: " + partes.length);
Saída esperada:
Elementos:
- maçã
- banana
- laranja
Comprimento do array: 3
Como observado, a string vazia que viria após a última vírgula foi descartada.
Exemplo 2: Múltiplos Delimitadores Finais
Se houver vários delimitadores consecutivos no final, o comportamento é o mesmo: todas as strings vazias resultantes no final são ignoradas.
String valores = "10,20,30,,,";
String[] elementos = valores.split(",");
System.out.println("Elementos:");
for (String elemento : elementos) {
System.out.println(" - " + elemento);
}
System.out.println("Comprimento do array: " + elementos.length);
Saída esperada:
Elementos:
- 10
- 20
- 30
Comprimento do array: 3
Independentemente do número de delimitadores finais, os elementos vazios correspondentes são reomvidos.
Exemplo 3: Delimitadores no Início ou no Meio
É importante notar que apenas os elementos vazios *finais* são descartados. Delimitadores no início ou no meio que resultam em strings vazias são mentidas.
String listaMista = ",itemA,,itemB";
String[] itens = listaMista.split(",");
System.out.println("Elementos:");
for (String item : itens) {
System.out.println(" - " + item);
}
System.out.println("Comprimento do array: " + itens.length);
Saída esperada:
Elementos:
-
- itemA
-
- itemB
Comprimento do array: 4
Aqui, as strings vazias correspondentes aos delimitadores iniciais e intermediários foram incluídas no array.
limit > 0
Quando limit é um valor positivo, o padrão será aplicado no máximo limit - 1 vezes. O array resultante terá um comprimento máximo de limit. A última string do array conterá o restante da string original, mesmo que ela contenha o delimitador.
Exemplo: Definindo um Número Máximo de Partes
Se quisermos dividir uma string em um número específico de partes, o limit positivo é ideal.
String caminhoArquivo = "pasta1/subpasta2/arquivo.txt/backup";
String[] segmentos = caminhoArquivo.split("/", 3); // Limita a 3 segmentos
System.out.println("Segmentos:");
for (String segmento : segmentos) {
System.out.println(" - " + segmento);
}
System.out.println("Comprimento do array: " + segmentos.length);
Saída esperada:
Segmentos:
- pasta1
- subpasta2
- arquivo.txt/backup
Comprimento do array: 3
Neste caso, o delimitador foi aplicado duas vezes (limit - 1 = 2), resultando em três elementos. O restante da string após a segunda divisão foi incluído como o terceiro elemento.
Se o limit for maior que o número máximo de divisões possíveis, o método simplesmente dividirá a string completamente, e o array terá o número total de partes. Por exemplo, "a,b,c".split(",", 10) resultaria em ["a", "b", "c"].
limit < 0
Quando limit é um valor negativo, o método aplica o padrão o máximo de vezes possível, e *todas* as substrings resultantes são incluídas no array, sem descartar quaisquer strings vazias, mesmo as que aparecem no final. Isso é útil quando você precisa manter todos os elementos, incluindo os vazios, independentemente da sua posição.
Exemplo: Mantendo Todos os Elementos Vazios
Vamos revisitar o exemplo com um delimitador final, mas agora usando um limit negativo.
String registro = "campoA,campoB,,campoD,";
String[] campos = registro.split(",", -1); // Mantém todos os elementos vazios
System.out.println("Campos:");
for (String campo : campos) {
System.out.println(" - '" + campo + "'"); // Adicionado aspas para visualizar strings vazias
}
System.out.println("Comprimento do array: " + campos.length);
Saída esperada:
Campos:
- 'campoA'
- 'campoB'
- ''
- 'campoD'
- ''
Comprimento do array: 5
Neste cenário, todas as strings vazias, tanto as intermediárias quanto a final, foram preservadas no array resultante. A distinção entre diferentes valores negativos (como -1, -2, etc.) não altera o comportamento fundamental; qualquer valor negativo resulta no mesmo comportamento de inclusão total de strings vazias.