JavaRush /Blogue Java /Random-PT /Introdução a String, StringBuffer e StringBuilder em Java...

Introdução a String, StringBuffer e StringBuilder em Java

Publicado no grupo Random-PT
Existem três classes em Java para trabalhar com dados de texto: String , StringBuffer e StringBuilder . Todo desenvolvedor encontra o primeiro logo no início do aprendizado da linguagem. E os dois restantes? Quais são suas diferenças e quando é melhor usar uma ou outra classe? Em geral a diferença entre eles é pequena, mas é melhor entender tudo na prática :) Introdução a String, StringBuffer e StringBuilder em Java - 1

Classe de cordas

Esta classe representa uma sequência de caracteres. Todos os literais de string definidos em programas, como "This is String" são instâncias da classe String. String tem duas características fundamentais:
  • esta é uma classe imutável
  • esta é a aula final
Em geral, a classe String não pode ter filhos ( final) e as instâncias da classe não podem ser modificadas após a criação ( immutable). Isso dá à classe String diversas vantagens importantes:
  1. Devido à imutabilidade, o código hash de uma instância da classe String é armazenado em cache. Ele não precisa ser avaliado todas as vezes porque os valores dos campos do objeto nunca serão alterados após sua criação. Isso proporciona alto desempenho ao usar esta classe como chave para arquivos HashMap.

  2. A classe String pode ser usada em um ambiente multithread sem sincronização adicional.

  3. Outra característica da classe String é que ela sobrecarrega o +operador " " em Java. Portanto, a concatenação (adição) de strings é bastante simples:

public static void main(String[] args) {
    String command = "Follow" + " " + "the" + " " + "white" + " " + "rabbit";
    System.out.println(command); // Follow the white rabbit
}
Nos bastidores, a concatenação de strings é realizada pela classe StringBuilder ou StringBuffer (a critério do compilador) e um método append(falaremos sobre essas classes um pouco mais tarde). Se adicionarmos instâncias da classe String com instâncias de outras classes, estas últimas serão reduzidas a uma representação de string:
public static void main(String[] args) {
    Boolean b = Boolean.TRUE;
    String result = "b is " + b;
    System.out.println(result); //b is true
}
Esta é outra propriedade interessante da classe String: objetos de qualquer classe podem ser convertidos em uma representação de string usando o método toString()definido na classe Objecte herdado por todas as outras classes. Freqüentemente, o método toString() em um objeto é chamado implicitamente. Por exemplo, quando exibimos algo na tela ou adicionamos uma String a um objeto de outra classe. A classe String possui mais um recurso. Todos os literais de string definidos no código Java, como "asdf", são armazenados em cache em tempo de compilação e adicionados ao chamado pool de strings. Se executarmos o seguinte código:
String a = "Wake up, Neo";
String b = "Wake up, Neo";

System.out.println(a == b);
Veremos true no console porque as variáveis a​​na verdade bse referirão à mesma instância da classe String que foi adicionada ao conjunto de strings em tempo de compilação. Ou seja, não são criadas instâncias diferentes da classe com o mesmo valor e a memória é salva.

Imperfeições:

Não é difícil adivinhar que a classe String é necessária principalmente para trabalhar com strings. Mas, em alguns casos, os recursos acima da classe String podem passar de vantagens a desvantagens. Depois que as strings são criadas no código Java, muitas operações são frequentemente executadas nelas:
  • conversão de strings em registros diferentes;
  • extração de substring;
  • concatenação;
  • etc.
Vejamos este código:
public static void main(String[] args) {

    String s = " Wake up, Neo! ";
    s = s.toUpperCase();
    s = s.trim();

    System.out.println("\"" + s + "\"");
}
À primeira vista, parece que acabamos de traduzir a frase “Acorde, Neo!” para maiúsculas, removeu espaços extras desta string e colocou-a entre aspas. Na verdade, devido à imutabilidade da classe String, como resultado de cada operação, novas instâncias de string são criadas e as antigas são descartadas, gerando uma grande quantidade de lixo. Como evitar o desperdício de memória?

Classe StringBuffer

Para lidar com a criação de lixo temporário devido a modificações em um objeto String, você pode usar a classe StringBuffer. Esta é mutableuma aula, ou seja, mutável. Um objeto da classe StringBuffer pode conter um conjunto específico de caracteres, cujo comprimento e valor podem ser alterados chamando determinados métodos. Vamos ver como funciona essa aula. Para criar um novo objeto, utilize um de seus construtores, por exemplo:
  • StringBuffer() - criará um objeto vazio (sem caracteres)
  • StringBuffer(String str) - criará um objeto baseado na variável str (contendo todos os caracteres de str na mesma sequência)
Prática:
StringBuffer sb = new StringBuffer();
StringBuffer sb2 = new StringBuffer("Not empty");
A concatenação de strings via StringBuffer em Java é feita usando o append. Em geral, o método appendna classe StringBuffer é sobrecarregado de tal forma que pode aceitar quase qualquer tipo de dados:
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();

    sb.append(new Integer(2));
    sb.append("; ");
    sb.append(false);
    sb.append("; ");
    sb.append(Arrays.asList(1,2,3));
    sb.append("; ");

    System.out.println(sb); // 2; false; [1, 2, 3];
}
O método appendretorna o objeto no qual foi chamado (como muitos outros métodos), o que permite que seja chamado em uma “cadeia”. O exemplo acima pode ser escrito assim:
public static void main(String[] args) {
    StringBuffer sb = new StringBuffer();

    sb.append(new Integer(2))
            .append("; ")
            .append(false)
            .append("; ")
            .append(Arrays.asList(1,2,3))
            .append("; ");

    System.out.println(sb); // 2; false; [1, 2, 3];
}
A classe StringBuffer possui vários métodos para trabalhar com strings. Vamos listar os principais:
  • delete(int start, int end)— exclui uma substring de caracteres começando em position start, terminandoend
  • deleteCharAt(int index)— exclui o caractere na posiçãoindex
  • insert(int offset, String str)— insere uma linha strna posição offset. O método inserttambém está sobrecarregado e pode receber argumentos diferentes
  • replace(int start, int end, String str)- substituirá todos os caracteres de uma posição startpara outra endporstr
  • reverse()— inverte a ordem de todos os caracteres
  • substring(int start)- retornará uma substring começando na posição start
  • substring(int start, int end)- retornará uma substring começando de uma posição startpara outraend
Uma lista completa de métodos e construtores está na documentação oficial . Como funcionam os métodos acima? Vejamos na prática:
public static void main(String[] args) {
     String numbers = "0123456789";

     StringBuffer sb = new StringBuffer(numbers);

     System.out.println(sb.substring(3)); // 3456789
     System.out.println(sb.substring(4, 8)); // 4567
     System.out.println(sb.replace(3, 5, "ABCDE")); // 012ABCDE56789

     sb = new StringBuffer(numbers);
     System.out.println(sb.reverse()); // 9876543210
     sb.reverse(); // Return the original order

     sb = new StringBuffer(numbers);
     System.out.println(sb.delete(5, 9)); // 012349
     System.out.println(sb.deleteCharAt(1)); // 02349
     System.out.println(sb.insert(1, "One")); // 0One2349
    }

Vantagens:

  1. Como já mencionado, StringBuffer é uma classe mutável, portanto, trabalhar com ela não cria a mesma quantidade de lixo de memória que com String. Portanto, se forem feitas muitas modificações nas strings, é melhor usar StringBuffer.

  2. StringBuffer é uma classe thread-safe. Seus métodos são sincronizados e as instâncias podem ser usadas por vários threads simultaneamente.

Imperfeições:

Por um lado, a segurança do thread é uma vantagem da classe e, por outro lado, é uma desvantagem. Os métodos sincronizados são mais lentos que os métodos não sincronizados. É aqui que o StringBuilder entra em ação. Vamos descobrir que tipo de classe Java é essa - StringBuilder, quais métodos ela possui e quais são seus recursos.

Classe StringBuilder

StringBuilder em Java é uma classe que representa uma sequência de caracteres. É muito semelhante ao StringBuffer em todos os aspectos, exceto na segurança do thread. StringBuilder fornece uma API semelhante à do StringBuffer. Vamos demonstrar isso usando um exemplo já familiar, substituindo a declaração de variáveis ​​de StringBufer por StringBuilder:
public static void main(String[] args) {
    String numbers = "0123456789";

    StringBuilder sb = new StringBuilder(numbers);

    System.out.println(sb.substring(3)); //3456789
    System.out.println(sb.substring(4, 8)); //4567
    System.out.println(sb.replace(3, 5, "ABCDE")); //012ABCDE56789

    sb = new StringBuilder(numbers);
    System.out.println(sb.reverse()); //9876543210
    sb.reverse(); // Return the original order

    sb = new StringBuilder(numbers);
    System.out.println(sb.delete(5, 9)); //012349
    System.out.println(sb.deleteCharAt(1)); //02349
    System.out.println(sb.insert(1, "One")); //0One2349
}
A única diferença é que StringBuffer é thread-safe e todos os seus métodos são sincronizados, enquanto StringBuilder não é. Este é o único recurso. StringBuilder em Java é mais rápido que StringBuffer devido à não sincronização de métodos. Portanto, na maioria dos casos, exceto em um ambiente multithread, é melhor usar StringBuilder para um programa Java. Resumimos tudo em uma tabela comparativa das três classes:

String vs StringBuffer vs StringBuilder

Corda StringBuffer StringBuilder
Mutabilidade Immutable(Não) mutable(Sim) mutable(Sim)
Extensibilidade final(Não) final(Não) final(Não)
Segurança do fio Sim, devido à imutabilidade Sim, devido à sincronização Não
Quando usar Ao trabalhar com strings que raramente serão modificadas Ao trabalhar com strings que serão modificadas frequentemente em um ambiente multithread Ao trabalhar com strings que serão modificadas frequentemente em um ambiente de thread único
Você pode estudar este tópico com mais detalhes no segundo nível da missão Java Multithreading no curso JavaRush:
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION