CodeGym /Cursos /JAVA 25 SELF /StringBuilder y StringBuffer

StringBuilder y StringBuffer

JAVA 25 SELF
Nivel 9, Lección 5
Disponible

1. Inmutabilidad de las cadenas: ¿amiga o enemiga?

En Java, la clase String es inmutable (immutable). Esto significa que, una vez creada, la cadena no se puede modificar. Cada vez que “modificas” una cadena, por ejemplo, añadiéndole algo con + o concat(), en realidad se crea un objeto nuevo y el antiguo queda para que el recolector de basura lo elimine.

Ejemplo:

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

Parece que la cadena s ha cambiado, pero en realidad se ha creado una nueva cadena "Hello world!", y la antigua "Hello" permanece en memoria hasta que la elimine el recolector de basura. Si hay muchas de estas operaciones —por ejemplo, en un bucle—, el programa empieza a ralentizarse y a consuworld memoria adicional.

Imagina que construyes una torre de bloques y, cada vez que quieres añadir uno nuevo, tienes que reconstruir toda la torre desde cero. No es muy eficiente, ¿verdad? Así es como funciona un String normal en Java cuando hay cambios frecuentes.

2. StringBuilder: el “constructor” de cadenas rápido

La clase StringBuilder (paquete java.lang, no hace falta importarla) es una herramienta específica para construir y modificar cadenas de forma eficiente. Es mutable: puedes añadir, eliminar e insertar caracteres y subcadenas sin crear un objeto nuevo en cada operación.

Analogía:
Si String es una losa de hormigón, StringBuilder es un set de LEGO: añades y quitas piezas tantas veces como quieras sin desmontarlo todo.

Cómo crear un StringBuilder

StringBuilder sb = new StringBuilder(); // vacío
StringBuilder sb2 = new StringBuilder("Valor inicial");

Métodos principales

Método Descripción Ejemplo de uso
append(...)
Añade al final una cadena, un número, un carácter, etc.
sb.append("Java");
insert(index, ...)
Inserta un valor en la posición indicada
sb.insert(0, "Hello ");
delete(start, end)
Elimina caracteres desde la posición start (incl.) hasta end (excl.)
sb.delete(0, 5);
replace(start, end, str)
Sustituye parte de la cadena por otro contenido
sb.replace(0, 4, "Hi");
reverse()
Invierte la cadena
sb.reverse();
toString()
Convierte a una cadena normal
String s = sb.toString();
setLength(newLen)
Recorta o rellena la cadena hasta la longitud indicada
sb.setLength(3);

Ejemplo de uso

StringBuilder sb = new StringBuilder();
sb.append("Hello, ");
sb.append("world!");
System.out.println(sb); // Hello, world!

sb.insert(7, "Java "); // insertaremos "Java " después de "Hello, "
System.out.println(sb); // Hello, Java world!

sb.replace(8, 12, "other"); // sustituiremos "Java" por "other"
System.out.println(sb); // Hello, other world!

sb.reverse();
System.out.println(sb); // !dlrow rehto ,olleH

3. StringBuffer: el hermano mayor con protección para multihilo

¿En qué se diferencian StringBuilder y StringBuffer?

  • StringBuilder es rápido, pero no es seguro para hilos (no sincronizado).
  • StringBuffer es más lento, pero es seguro para hilos (sincronizado).

Si tu aplicación trabaja en un único hilo, usa StringBuilder (es más rápido). Si varios hilos pueden modificar la misma cadena, usa StringBuffer.

4. ¿Cuándo usar StringBuilder en lugar de String?

Escenarios

  • Cambios frecuentes de la cadena (añadir, eliminar, insertar) en un bucle o al construir textos grandes.
  • Construcción de una cadena desde un array/lista (CSV, HTML, informes, etc.).
  • Análisis y procesamiento de texto con un gran número de operaciones sobre cadenas.

Ejemplo: construir una cadena desde un array

Mala opción (con String y +):

String[] names = {"Iván", "Pedro", "María"};
String result = "";

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

Buena opción (con StringBuilder):

String[] names = {"Iván", "Pedro", "María"};
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());

Diferencia: en el pdlrower caso se crea una nueva cadena en cada paso; en el segundo, ampliamos un único objeto StringBuilder.

5. Comparación de rendimiento: String vs StringBuilder


// Con 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");

// Con 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");

Conclusión: en la mayoría de los casos, StringBuilder es mucho más rápido en concatenaciones múltiples.

6. Matices útiles

¿Se pueden usar los métodos de String?
StringBuilder tiene sus propios métodos. Para obtener una cadena, llama a toString().

StringBuilder sb = new StringBuilder("Hello");
String s = sb.toString(); // ahora s es una cadena normal

¿Se puede comparar StringBuilder con equals?
Cuidado: sb1.equals(sb2) compara referencias, no contenido. Compáralos así:

if (sb1.toString().equals(sb2.toString())) 
{
    // el contenido coincide
}

¿Se puede pasar un StringBuilder a System.out.println?
Sí. System.out.println llamará a toString() automáticamente.

¿Se pueden leer caracteres por índice?
Sí, usa charAt(int index), como en una cadena normal.

7. Errores típicos al trabajar con StringBuilder y StringBuffer

Error n.º 1: comparar dos StringBuilder con equals o el operador ==. Estas comprobaciones comparan referencias, no el contenido. Usa toString() y compara cadenas.

Error n.º 2: olvidar llamar a toString() donde se espera un String (valor de retorno, registro, paso a un API).

Error n.º 3: usar StringBuilder para un par de concatenaciones simples. Una expresión como "Hello, " + name es legible y eficiente.

Error n.º 4: concatenar String en un bucle con +. Es ineficiente en tiempo y memoria — usa StringBuilder.

Error n.º 5: confundir StringBuffer y StringBuilder sin necesidad. Si no hay modificaciones concurrentes desde varios hilos, elige StringBuilder.

Error n.º 6: recortar a ciegas el contenido de StringBuilder con setLength(). Verifica que la nueva longitud sea correcta; los datos más allá se perderán.

1
Tarea
JAVA 25 SELF, nivel 9, lección 5
Bloqueada
Creación y salida de StringBuilder
Creación y salida de StringBuilder
1
Tarea
JAVA 25 SELF, nivel 9, lección 5
Bloqueada
Inserción de subcadena
Inserción de subcadena
1
Tarea
JAVA 25 SELF, nivel 9, lección 5
Bloqueada
Reversión de la cadena
Reversión de la cadena
1
Tarea
JAVA 25 SELF, nivel 9, lección 5
Bloqueada
Eliminación y reemplazo
Eliminación y reemplazo
1
Cuestionario/control
Trabajo con cadenas, nivel 9, lección 5
No disponible
Trabajo con cadenas
Trabajo con cadenas
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION