Domine Substrings em Java: Guia Completo com Exemplos

Neste artigo, vamos explorar o conceito de substrings em Java. Além de fornecer uma explicação teórica detalhada, também apresentaremos exemplos de código prático para facilitar a compreensão. Vamos guiá-lo através do processo de criação de substrings e como identificar substrings dentro de uma string maior.

Antes de nos aprofundarmos, é crucial entender os fundamentos das strings e substrings.

O que são Strings e Substrings?

Em Java, uma string representa uma sequência de caracteres. Cada string em Java é um objeto que pode conter letras, números, símbolos e espaços em branco. Por outro lado, uma substring em Java é simplesmente uma porção ou um subconjunto de uma string.

Por exemplo, “Geek” é uma substring da string “etechpt.com”. Substrings permitem isolar partes específicas de uma string.

Se você tem o nome completo “John Doe” e quer extrair apenas o primeiro nome “John”, isso pode ser feito com substrings. Da mesma forma, se você tem uma lista de nomes como “John, Jack, Jolly” e precisa verificar se “John” está presente, também pode usar substrings para isso. Estes são apenas alguns exemplos. O domínio das substrings possibilita uma ampla gama de operações.

Agora que temos uma compreensão clara do conceito de substrings em Java, vamos explorar como criar e trabalhar com elas.

1. Usando o Método ‘substring()’

O método ‘substring()’ oferece uma maneira direta de criar substrings. Ele aceita um ou dois parâmetros: ‘startIndex’ ou ‘startIndex’ e ‘endIndex’, e retorna a substring desejada.

O método pode ser usado de duas formas, dependendo do número de parâmetros fornecidos. Vamos detalhar cada uma delas.

substring(int startIndex)

A primeira forma do método é ‘substring(startIndex)’. Aqui, apenas um valor inteiro é usado como entrada, representando a posição inicial da substring. O método retorna uma nova string que se estende do ‘startIndex’ fornecido até o final da string original.

Para ilustrar, veja o exemplo abaixo:

public class Substrings{    
    public static void main(String args[]){    
    String str="etechpt.com";    
    System.out.println("String Original: " + str);  
    System.out.println("Substring: " +str.substring(4)); // Índices começam em 0
    }  
   }

SAÍDA:

String Original: etechpt.com
Substring: pt.com

Na saída, vemos que a string de entrada é “etechpt.com” e o resultado é a substring “pt.com”. Ele extrai uma substring a partir do índice 4 (a quinta posição) até o fim da string.

substring(int startIndex, int endIndex)

Esta é outra maneira de usar o método ‘substring()’. Aqui, fornecemos dois valores inteiros: o índice inicial e o índice final. Para usar essa forma, chamamos o método como ‘substring(startIndex, endIndex)’.

Para uma melhor compreensão, vamos analisar o seguinte exemplo:

public class Substrings{    
    public static void main(String args[]){    
    String str="GeekFlareFans";    
    System.out.println("String Original: " + str);  
    System.out.println("Substring: " +str.substring(4,9));  // Substring do índice 4 ao 8.

    }  
   }

SAÍDA:

String Original: GeekFlareFans
Substring: Flare

Como você pode observar, com a string “GeekFlareFans”, obtemos a substring “Flare”. O índice inicial é 4 e o índice final é 9. A extração começa no elemento com índice 4 e termina imediatamente antes do índice 9. É crucial notar que o elemento no índice final não é incluído na substring resultante. Isso nos dá uma substring que inclui todos os elementos até o índice final, mas excluindo-o.

2. Usando o Método ‘split()’

O método ‘split()’ da classe String em Java é outra ferramenta poderosa para gerar substrings. Ele se torna especialmente útil quando múltiplas informações são armazenadas em uma string, utilizando um caractere separador comum.

A sintaxe menciona o termo “regex”, que pode parecer intimidador à primeira vista. Vamos entender o que é regex antes de prosseguirmos. Regex é uma abreviação de “Expressões Regulares”. Uma regex é uma sequência de caracteres que descreve um padrão dentro de uma string ou texto. No contexto do método ‘split()’, o regex é o nosso separador.

O método ‘split()’ pode receber até duas variáveis como entrada: uma string regex e um número inteiro de limite. O regex é o separador que, quando encontrado, divide a string original em duas partes – a parte antes do regex e a parte após o regex.

Por exemplo, se tentarmos dividir a string “abcdef” usando “bcd” como regex, teríamos as substrings “a” e “ef” como resultado.

O método retorna um array contendo as strings separadas. Podemos especificar apenas o regex ou o regex junto com o limite. Vamos explorar as várias maneiras de usar este método.

split(String regex)

A primeira forma recebe apenas a string regex no formato ‘split(regex)’. Não possui variável limite; portanto, retorna todas as substrings separadas em uma matriz.

Vamos obter uma compreensão mais clara com o seguinte código:

public class Substrings{    
    public static void main(String args[]){    
    String str="Geek%Flare";
    String[] substrings=str.split("%");
    System.out.println("String Original: " + str);
    System.out.println("Primeira Substring: " + substrings[0]);
    System.out.println("Segunda Substring: " + substrings[1]);
     
    }  
}

SAÍDA:

String Original: Geek%Flare
Primeira Substring: Geek
Segunda Substring: Flare

Como visto no código, a string fornecida possui o separador regex “%”. Este não precisa ser um único caractere; pode ser qualquer string com qualquer número de caracteres. O método ‘split()’ ignora esse regex e nos entrega todas as strings que foram separadas por ele. As substrings são armazenadas dentro de um array.

No código, a string fornecida é “Geek%Flare”. Assim, obtemos um array com dois elementos, que são “Geek” e “Flare”. Posteriormente, acessamos esses elementos com seus respectivos índices (0 e 1) e imprimimos “Geek” e “Flare” no console.

É importante notar que, se nenhum parâmetro for passado para o método, ele simplesmente lançará um erro. No entanto, se fornecermos uma string vazia (“”) como regex, obteremos cada caractere individual como uma substring. Veja o exemplo a seguir:

import java.util.Arrays;

public class Substrings{    
    public static void main(String args[]){    
    String str="Geek%Flare";
    String[] substrings=str.split("");
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SAÍDA:

[G, e, e, k, %, F, l, a, r, e]

Este exemplo ilustra que quando o parâmetro regex é uma string vazia, o método retorna todos os caracteres como substrings separados. Isso é claramente visível na saída do array do método ‘split()’.

split(String regex, int limite)

A segunda variante deste método nos oferece mais controle sobre a saída e permite ajustar o comportamento do ‘split()’. Aqui, fornecemos dois parâmetros: o regex e um parâmetro de limite, no formato ‘split(regex, limite)’.

O ‘limite’ é o número máximo de substrings que serão geradas. Dependendo do valor do limite, existem três possibilidades:

Caso 1: Se limite > 0, o array resultante conterá a saída, mas a divisão será aplicada no máximo (limite-1) vezes. O array não conterá mais elementos que o limite especificado, e toda a string restante que não foi dividida será armazenada como está. Veja este exemplo para melhor entendimento:

import java.util.Arrays;

public class Substrings{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%the%best";
    String[] substrings=str.split("%",2);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SAÍDA:

[Geek, Flare%is%the%best]

Observe na saída que o array possui apenas dois elementos, que é o número fornecido no parâmetro de limite. Além disso, a divisão é aplicada apenas uma vez, ou seja, (limite -1) vezes.

No entanto, se o regex ocorrer duas vezes em sequência (“%%”), haverá substrings vazias. Veja este trecho de código:

import java.util.Arrays;

public class Substrings{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%%the%best%%%";
    String[] substrings=str.split("%",5);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SAÍDA:

[Geek, Flare, is, , the%best%%%]

Basicamente, se “%” é seguido por outro “%” ou pelo final da string, ele se transforma em uma substring vazia.

Caso 2: Se limite < 0, a ação de divisão será aplicada o máximo de vezes possível, sem limite para o tamanho do array. No entanto, o array conterá substrings vazias se o regex ocorrer duas vezes em sequência (“%%”).

import java.util.Arrays;

public class Substrings{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%%the%best%%%";
    String[] substrings=str.split("%",-1);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SAÍDA:

[Geek, Flare, is, , the, best, , , ]

A saída mostra que a divisão é aplicada o máximo possível, e substrings vazias estão presentes.

Caso 3: Se limite = 0, a ação de divisão também será aplicada o máximo possível, mas todas as substrings vazias no final da string serão descartadas do array.

import java.util.Arrays;

public class Substrings{    
    public static void main(String args[]){    
    String str="Geek%Flare%is%%the%best%%%";
    String[] substrings=str.split("%",0);
    System.out.println(Arrays.toString(substrings));
     
    }  
}

SAÍDA:

[Geek, Flare, is, , the, best]

Podemos observar que a saída é semelhante àquela quando limite = -1, mas não há substrings vazias à direita. Em outras palavras, as substrings vazias no final do array de substrings são ignoradas.

Importante: se o regex não estiver presente na string, o método retornará a string original inteira como resultado.

Verificando se uma String Contém uma Substring

Além de criar substrings, também podemos verificar se uma substring específica existe dentro de uma string maior. Isso é rápido e fácil de fazer, útil em diversas situações. Existem vários métodos para nos ajudar nisso. Vamos analisá-los.

Usando o Método ‘contains()’

Podemos verificar a existência de uma substring usando o método ‘contains()’. Este método da classe String aceita uma string como entrada (a nossa substring) e retorna um valor booleano indicando se a substring está presente na string ou não. Este método pode ser usado em blocos ‘if-else’, operadores ternários e outros contextos para implementar lógica complexa.

Veja alguns exemplos:

public class Substrings{    
    public static void main(String args[]){    
    String str="etechpt.com";    
    System.out.println("Contém 'pt'?  " + str.contains("pt"));  
    }  
}

SAÍDA:

Contém 'pt'?  true

O código verifica se a string “etechpt.com” contém a palavra “pt” e, por encontrá-la, retorna o booleano ‘true’, confirmando a presença da substring.

public class Substrings{    
    public static void main(String args[]){    
    String str="etechpt.com";    
    System.out.println("Contém 'Flare1'?  " + str.contains("Flare1"));  
    }  
}

SAÍDA:

Contém 'Flare1'?  false

Este exemplo ilustra que, se a substring não estiver presente, o método retornará ‘false’, indicando sua ausência. Assim, podemos verificar com segurança se uma substring está presente.

Encontrando a Posição de uma Substring

1. Usando ‘indexOf()’

O método ‘indexOf()’ pode ser usado para verificar a existência de uma substring e também para encontrar seu índice. Ele aceita uma string ou um caractere como entrada e retorna o índice da sua primeira ocorrência. No entanto, ele só retorna o índice da primeira ocorrência e não pode confirmar se existem outras ocorrências. Além disso, se a substring não existir, o método retornará -1.

Vamos explorar um pouco mais este método:

public class Substrings{    
    public static void main(String args[]){    
    String str="GeekFlareGeekFlare";    
    System.out.println("Índice de 'Flare': " + str.indexOf("Flare"));  
    }  
}

SAÍDA:

Índice de 'Flare': 4

Neste exemplo, a primeira ocorrência da substring “Flare” começa no índice 4 da string “GeekFlareGeekFlare”. Então, como esperado, a função retornou o índice.

2. Usando ‘lastIndexOf()’

O método ‘lastIndexOf()’ é bastante similar ao ‘indexOf()’. Ambos os métodos recebem a substring como entrada e retornam o índice de sua posição. Ambos retornam -1 quando não encontram a substring.

A principal diferença é que enquanto o ‘indexOf()’ retorna o índice da primeira ocorrência, ‘lastIndexOf()’ retorna a última ocorrência.

Veja um exemplo em código:

public class Substrings{    
    public static void main(String args[]){    
    String str="GeekFlareGeekFlare";    
    System.out.println("Último índice de 'Flare': "+ str.lastIndexOf("Flare"));  
    }  
}

SAÍDA:

Último índice de 'Flare': 13

Nesta saída, vemos que o método ‘lastIndexOf()’ retorna o índice da última ocorrência da substring “Flare” na string “GeekFlareGeekFlare”, como esperado.

Perguntas Frequentes

Como usar o método ‘split()’ para criar substrings não vazias?

Se houver múltiplas instâncias da regex em sequência na string original (“Hello%%Hi”, onde regex é “%”), o método ‘split()’ considera a primeira instância como um ponto de quebra e as restantes geram strings vazias. Para evitar isso, podemos especificar o parâmetro de limite como 0. Assim, o método retornará apenas substrings não vazias.

‘indexOf()’ retorna índices de todas as instâncias de uma substring?

Não, ‘indexOf()’ não retorna os índices de todas as instâncias de uma substring. Com ‘indexOf()’, obtemos um valor inteiro que contém o índice da primeira ocorrência. Se a substring não for encontrada, o método retorna -1.

O que o método ‘substring()’ retorna se os índices fornecidos não existirem na string?

Se os índices inicial e final fornecidos não existirem na string, o compilador lançará um erro. O erro será do tipo “java.lang.StringIndexOutOfBoundsException” e o programa será interrompido.

Conclusão

Neste artigo, abordamos diversos métodos e fundamentos essenciais para trabalhar com substrings em Java. Aprendemos a criar substrings e verificar sua existência dentro de strings maiores. Este conhecimento é fundamental para o desenvolvimento eficiente em Java. Recomendamos que você pratique mais com os exemplos fornecidos para obter uma compreensão completa.

Em seguida, você pode consultar nossa lista de perguntas para entrevistas sobre Java.