Concatenação de Strings em Java
Une strings em Java com o operador +, concat() e StringBuilder, e compare o desempenho de cada abordagem.
"Concatenação" significa simplesmente unir strings uma após a outra. Java oferece várias formas de fazer isso — +, concat, String.format, blocos de texto, StringBuilder, String.join. Elas diferem em legibilidade e, quando usadas em laços, em desempenho.
O operador +
+ é a forma mais comum:
String first = "Ada";
String last = "Lovelace";
String full = first + " " + last; // "Ada Lovelace"Ele também converte valores não-string em strings via toString():
int age = 36;
String s = "Age: " + age; // "Age: 36"Por baixo dos panos, o compilador transforma a + b + c em um único StringBuilder.append(...).append(...).toString(). Portanto, uma expressão encadeada com + é eficiente.
concat
String.concat(other) retorna esta string seguida de other:
"Hello, ".concat("World!"); // "Hello, World!"É efetivamente o mesmo que +, mas aceita apenas um String (sem conversão automática). A maioria do código usa simplesmente +.
String.format e formatted
Para concatenação com várias partes e formatação específica por tipo, String.format é mais limpo do que longas cadeias de +:
String name = "Ada";
int age = 36;
String s = String.format("%s is %d years old", name, age);Desde o Java 15, o método de instância formatted é equivalente e é lido da esquerda para a direita:
"%s is %d years old".formatted(name, age);Blocos de texto para múltiplas linhas
Para strings com múltiplas linhas, a sintaxe de bloco de texto (Java 15+) evita longas cadeias com \n:
String json = """
{
"name": "%s",
"age": %d
}
""".formatted(name, age);StringBuilder — para laços
Strings em Java são imutáveis — uma vez criada, uma String nunca pode ser alterada. Portanto, cada + em uma String produz um objeto completamente novo. Em um laço com milhares de iterações, isso gera muitos objetos de vida curta e muitas cópias. Use StringBuilder em vez disso — ele possui um único buffer interno mutável que cresce no lugar:
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
sb.append("line ").append(i).append("\n");
}
String result = sb.toString();Os métodos do StringBuilder que você mais usará:
append(any)— adiciona ao final (retorna o próprio builder para encadeamento).insert(index, any)— insere em uma posição.delete(start, end)— remove um intervalo.reverse()— inverte o conteúdo do builder.length()esetLength(n)— lê / trunca.toString()— produz aStringfinal.
Existe também o StringBuffer, que é idêntico mas seguro para threads (todos os métodos são synchronized). Você quase nunca precisará dele — use StringBuilder a menos que realmente precise compartilhar o builder entre threads.
String.join — para coleções
Quando você tem uma coleção de strings e um separador, String.join é a opção mais limpa:
String csv = String.join(",", "a", "b", "c"); // "a,b,c"
String csv2 = String.join(", ", List.of("a", "b", "c")); // "a, b, c"Para junções mais avançadas (coletores, inclusão condicional), veja Collectors.joining dos streams mais adiante no livro.
Quando usar cada abordagem
Uma árvore de decisão simplificada:
- Uma ou duas partes, legível da esquerda para a direita →
+. - Várias partes com formatação por tipo →
String.formatouformatted. - Literal de múltiplas linhas → bloco de texto, opcionalmente com
.formatted. - Construção peça por peça em um laço →
StringBuilder. - Unindo uma coleção com um separador →
String.join.
Para concatenações pequenas, compiladores modernos e a JVM (com a concatenação de strings baseada em invokedynamic introduzida no Java 9) tornam o + muito rápido — desempenho não é razão para evitá-lo em casos simples.
Uma demonstração do caso com laço
O que vem a seguir
Caracteres Especiais e Sequências de Escape em Java — o que \n, \t, \" e as sequências de escape Unicode fazem.