W3docs

Concatenación de cadenas en Java

Une cadenas en Java con el operador +, concat() y StringBuilder, y compara su rendimiento.

"Concatenación" significa unir cadenas de texto una tras otra. Java ofrece varias formas de hacerlo: +, concat, String.format, bloques de texto, StringBuilder y String.join. Difieren en legibilidad y, cuando se usan en bucles, en rendimiento.

El operador +

+ es la forma más habitual:

String first = "Ada";
String last = "Lovelace";
String full = first + " " + last;     // "Ada Lovelace"

También convierte valores que no son cadenas a string mediante su toString():

int age = 36;
String s = "Age: " + age;             // "Age: 36"

Internamente, el compilador transforma a + b + c en una única llamada StringBuilder.append(...).append(...).toString(). Por lo tanto, una expresión encadenada con + es eficiente.

concat

String.concat(other) devuelve esta cadena seguida de other:

"Hello, ".concat("World!");    // "Hello, World!"

Es prácticamente igual que +, pero solo acepta un String (sin conversión automática). La mayoría del código simplemente usa +.

String.format y formatted

Para concatenar múltiples fragmentos con formato específico por tipo, String.format es más limpio que largas cadenas de +:

String name = "Ada";
int age = 36;
String s = String.format("%s is %d years old", name, age);

Desde Java 15, el método de instancia formatted es equivalente y se lee de izquierda a derecha:

"%s is %d years old".formatted(name, age);

Bloques de texto para múltiples líneas

Para cadenas de varias líneas, la sintaxis de bloques de texto (Java 15+) evita largas cadenas con \n:

String json = """
        {
          "name": "%s",
          "age": %d
        }
        """.formatted(name, age);

StringBuilder — para bucles

Las cadenas en Java son inmutables: una vez creada, una String nunca puede cambiar. Por eso, cada + sobre una String genera un objeto completamente nuevo. En un bucle con miles de iteraciones, eso supone mucha basura de corta vida y muchas copias. Usa StringBuilder en su lugar: dispone de un único buffer interno mutable que crece en el mismo lugar:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append("line ").append(i).append("\n");
}
String result = sb.toString();

Los métodos de StringBuilder que más usarás:

  • append(any) — añade al final (devuelve el propio builder para poder encadenar llamadas).
  • insert(index, any) — inserta en una posición.
  • delete(start, end) — elimina un rango.
  • reverse() — invierte el contenido del builder.
  • length() y setLength(n) — leer / truncar.
  • toString() — produce la String final.

También existe StringBuffer, que es idéntico pero seguro para hilos (todos sus métodos son synchronized). Casi nunca lo necesitarás; usa StringBuilder salvo que realmente compartas el builder entre hilos.

String.join — para colecciones

Cuando tienes una colección de cadenas y un separador, String.join es la opción más limpia:

String csv = String.join(",", "a", "b", "c");        // "a,b,c"
String csv2 = String.join(", ", List.of("a", "b", "c"));   // "a, b, c"

Para opciones de unión más avanzadas (collectors, inclusión condicional), consulta Collectors.joining de los streams más adelante en el libro.

Cuándo usar cada opción

Un árbol de decisión aproximado:

  • Uno o dos fragmentos, legible de izquierda a derecha+.
  • Varios fragmentos con formato por tipoString.format o formatted.
  • Literal de varias líneas → bloque de texto, opcionalmente con .formatted.
  • Construir pieza a pieza en un bucleStringBuilder.
  • Unir una colección con un separadorString.join.

Para concatenaciones pequeñas, los compiladores modernos y la JVM (con la concatenación de strings basada en invokedynamic introducida en Java 9) hacen que + sea muy rápido: el rendimiento no es razón para evitarlo en casos simples.

Demostración del caso con bucles

java— editable, runs on the server

Qué sigue

Caracteres especiales y secuencias de escape en Java — qué hacen \n, \t, \" y los escapes Unicode.

Práctica

Práctica
¿Qué enfoque es mejor para construir una cadena larga dentro de un bucle de 10 000 iteraciones?
¿Qué enfoque es mejor para construir una cadena larga dentro de un bucle de 10 000 iteraciones?
Was this page helpful?