La construcción de texto consiste en combinar o transformar cadenas sin crear objetos intermedios innecesarios.
En el artículo anterior aprendimos que los String son inmutables. Las operaciones producen un nuevo resultado en lugar de modificar el objeto original.
Para operaciones sencillas, no pasa nada. Pero imagina que estás leyendo un archivo de 10.000 líneas y quieres unirlas todas en una sola variable.
String texto = "";
for (int i = 0; i < 10000; i++) {
texto = texto + " linea " + i; // ¡CRIMEN CONTRA LA RAM!
}
En cada vuelta del bucle, Java tiene que copiar todo el texto acumulado para añadirle un trocito más. Esto tiene una complejidad de O(n²). Es lento, ineficiente y puede bloquear tu servidor.
Para solucionar esto, Java nos da herramientas para trabajar con cadenas mutables.
StringBuilder: el cuaderno de notas
La clase java.lang.StringBuilder es como un String pero sin la restricción de inmutabilidad. Es un buffer de caracteres redimensionable.
Imagina que String es un cartel impreso en piedra (no se puede editar), y StringBuilder es un cuaderno de anillas (puedes añadir y quitar hojas cuando quieras).
Cómo usarlo
El patrón estándar es: crear el builder, modificarlo a placer y, al final, convertirlo a String fijo.
// 1. Crear el Builder
StringBuilder sb = new StringBuilder();
// 2. Modificar (append es súper rápido)
sb.append("Hola");
sb.append(" ");
sb.append("Mundo");
// Podemos encadenar llamadas (Fluent API)
sb.append(" desde").append(" Java");
// Otras operaciones útiles
sb.insert(5, "querido "); // Insertar en medio
sb.reverse(); // Invertir el texto (odnuM aloH...)
// 3. Convertir a String final
String resultado = sb.toString();
¿Cuándo usarlo?
Usa StringBuilder cuando acumules texto en un bucle o mediante muchas operaciones sucesivas. Para concatenaciones sencillas, + es más legible y el compilador puede optimizarla mediante los mecanismos de concatenación de la JVM.
StringBuilder vs StringBuffer
Esta es la pregunta clásica de entrevista de trabajo. Ambos hacen lo mismo (cadenas mutables), tienen los mismos métodos y se usan igual. ¿Cuál es la diferencia?
StringBuffer(Legacy): Es la clase original (Java 1.0). Es Synchronized (Thread-Safe). Esto significa que si dos hilos intentan escribir a la vez, se bloquean para no pisarse. Esa seguridad tiene un coste: es lento.StringBuilder(Moderno): Llegó en Java 5. No es sincronizado. Es mucho más rápido.
Resumen:
En código de un solo hilo suele preferirse StringBuilder. StringBuffer mantiene métodos sincronizados y todavía puede ser útil cuando varias operaciones simples comparten la misma instancia, aunque a menudo es mejor evitar ese estado mutable compartido.
Formateo moderno: text blocks (Java 15+)
Durante 25 años, escribir HTML, JSON o SQL dentro de una clase Java era un infierno de comillas escapadas y signos más.
// EL HORROR (Java antiguo)
String html = "<html>\n" +
" <body>\n" +
" <h1>Hola</h1>\n" +
" </body>\n" +
"</html>";
Afortunadamente, desde Java 15, tenemos los Text Blocks. Se definen con tres comillas dobles """.
// LA GLORIA (Java 15+)
String html = """
<html>
<body>
<h1>Hola</h1>
</body>
</html>
""";
Java es lo suficientemente inteligente para:
- Ignorar la indentación accidental del código (alinea el texto a la izquierda basándose en la posición de las comillas de cierre).
- No necesitar escapar las comillas dobles interiores.
- Interpretar los saltos de línea automáticamente.
Inyectando variables (formatted)
Los Text Blocks combinan genial con el nuevo método .formatted() (o String.format), que funciona igual que el printf que vimos antes.
String nombre = "Luis";
String json = """
{
"usuario": "%s",
"activo": true
}
""".formatted(nombre);