CodeGym /Cursos /JAVA 25 SELF /StringBuilder e StringBuffer

StringBuilder e StringBuffer

JAVA 25 SELF
Nível 9 , Lição 5
Disponível

1. Imutabilidade de String: amiga ou inimiga?

Em Java, a classe String é imutável (immutable). Isso significa que, depois de criada, a string não pode ser alterada. Toda vez que você “altera” uma string, por exemplo, adicionando algo com + ou concat(), na verdade é criado um novo objeto, e o antigo vai para a lixeira da história (e da memória).

Exemplo:

String s = "Hello";
s = s + " world!";
System.out.println(s); // Hello world!

Parece que a string s mudou, mas na realidade foi criada uma nova string "Hello world!", e a antiga "Hello" permanece na memória até que o coletor de lixo a remova. Se tais operações forem muitas — por exemplo, em um loop — o programa começa a ficar lento e a usar memória desnecessária.

Imagine que você está construindo uma torre de blocos e, sempre que quer adicionar um novo bloco, precisa reconstruir a torre inteira do zero. Nada econômico, certo? É assim que o String comum funciona em Java quando há alterações frequentes.

2. StringBuilder: o “construtor” de strings rápido

A classe StringBuilder (pacote java.lang, não é necessário importar) é uma ferramenta especial para montar e modificar strings de forma eficiente. Ela é mutável (mutable): você pode adicionar, remover e inserir caracteres e substrings sem criar um novo objeto para cada operação.

Analogias:
Se String é uma laje de concreto, então StringBuilder é um conjunto LEGO: você adiciona e remove peças à vontade sem desmontar tudo.

Como criar um StringBuilder

StringBuilder sb = new StringBuilder(); // vazio
StringBuilder sb2 = new StringBuilder("Valor inicial");

Principais métodos

Método Descrição Exemplo de uso
append(...)
Adicionar ao final uma string, número, caractere etc.
sb.append("Java");
insert(index, ...)
Inserir o valor na posição especificada
sb.insert(0, "Hello ");
delete(start, end)
Remover caracteres da posição start (incl.) até end (excl.)
sb.delete(0, 5);
replace(start, end, str)
Substituir parte da string por outro conteúdo
sb.replace(0, 4, "Hi");
reverse()
Inverter a string
sb.reverse();
toString()
Converter para uma string normal
String s = sb.toString();
setLength(newLen)
Cortar ou completar a string até o comprimento especificado
sb.setLength(3);

Exemplo de uso

StringBuilder sb = new StringBuilder();
sb.append("Olá, ");
sb.append("mundo!");
System.out.println(sb); // Olá, mundo!

sb.insert(7, "Java "); // vamos inserir "Java " depois de "Olá, "
System.out.println(sb); // Olá, Java mundo!

sb.replace(8, 12, "outro"); // vamos substituir "Java" por "outro"
System.out.println(sb); // Olá, outro mundo!

sb.reverse();
System.out.println(sb); // !odnum ortuo ,álO

3. StringBuffer: irmão mais velho com segurança para múltiplas threads

Qual é a diferença entre StringBuilder e StringBuffer?

  • StringBuilder — rápido, mas não é thread-safe (não sincronizado).
  • StringBuffer — mais lento, porém thread-safe (sincronizado).

Se seu aplicativo funciona em uma única thread, use StringBuilder (mais rápido). Se várias threads puderem modificar a mesma string, use StringBuffer.

4. Quando usar StringBuilder em vez de String?

Cenários

  • Alterações frequentes na string (adição, remoção, inserção) em loops ou ao montar textos grandes.
  • Montagem de uma string a partir de um array/lista (CSV, HTML, relatórios etc.).
  • Parsing e processamento de texto com muitas operações sobre a string.

Exemplo: montagem de string a partir de um array

Maneira ruim (com String e +):

String[] names = {"Ivan", "Pyotr", "Maria"};
String result = "";

for (int i = 0; i < names.length; i++) 
{
    result += names[i];
    if (i < names.length - 1) 
    {
        result += ", ";
    }
}
System.out.println(result);

Maneira boa (com StringBuilder):

String[] names = {"Ivan", "Pyotr", "Maria"};
StringBuilder sb = new StringBuilder();

for (int i = 0; i < names.length; i++) 
{
    sb.append(names[i]);
    if (i < names.length - 1) 
    {
        sb.append(", ");
    }
}
System.out.println(sb.toString());

Diferença: no primeiro caso, a cada passo é criada uma nova string; no segundo, nós vamos acumulando em um único objeto StringBuilder.

5. Comparação de desempenho: String vs StringBuilder


// Usando String
long t1 = System.currentTimeMillis();
String s = "";
for (int i = 0; i < 10000; i++)
{
    s += i + " ";
}
long t2 = System.currentTimeMillis();
System.out.println("String: " + (t2 - t1) + " ms");

// Usando StringBuilder
t1 = System.currentTimeMillis();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++)
{
    sb.append(i).append(" ");
}
s = sb.toString();
t2 = System.currentTimeMillis();
System.out.println("StringBuilder: " + (t2 - t1) + " ms");

Conclusão: na maioria dos casos, StringBuilder é ordens de grandeza mais rápido em concatenações múltiplas.

6. Dicas úteis

Posso usar os métodos de String?
StringBuilder tem seus próprios métodos. Para obter uma string, chame toString().

StringBuilder sb = new StringBuilder("Hello");
String s = sb.toString(); // agora s é uma string comum

Posso comparar StringBuilder com equals?
Cuidado: sb1.equals(sb2) compara referências, não o conteúdo. Compare assim:

if (sb1.toString().equals(sb2.toString())) 
{
    // o conteúdo é igual
}

Posso passar StringBuilder para System.out.println?
Sim. System.out.println chamará toString() automaticamente.

Posso ler caracteres por índice?
Sim, use charAt(int index), como em uma string comum.

7. Erros típicos ao trabalhar com StringBuilder e StringBuffer

Erro nº 1: comparar dois StringBuilder com equals ou o operador ==. Essas verificações comparam referências, não o conteúdo. Use toString() e compare as strings.

Erro nº 2: esquecer de chamar toString() onde é esperado um String (retorno de método, logging, passagem para APIs).

Erro nº 3: usar StringBuilder para um par de concatenações simples. A forma "Hello, " + name é legível e eficiente.

Erro nº 4: concatenar String em um loop usando +. Isso é ineficiente em tempo e memória — use StringBuilder.

Erro nº 5: confundir StringBuffer com StringBuilder sem necessidade. Se não houver modificação simultânea por múltiplas threads, prefira StringBuilder.

Erro nº 6: truncar o conteúdo de StringBuilder com setLength() sem pensar. Verifique a correção do novo tamanho; os dados após ele serão perdidos.

1
Pesquisa/teste
Trabalhando com strings, nível 9, lição 5
Indisponível
Trabalhando com strings
Trabalhando com strings
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION