Saltar a contenido

💾 String en Java

🧠 ¿Qué es un String?

  • Un String representa texto inmutable (no cambia después de crearse).
  • Internamente es una secuencia de char (unidades UTF-16).
  • Java optimiza memoria con el String Pool: los literales "hola" pueden compartirse.
  • Es una clase (java.lang.String), no un tipo de datos primitivo.
String a = "hola";            // literal (va al String Pool)
String b = "hola";            // reutiliza el mismo literal
String c = new String("hola"); // FUERA del pool (no recomendado)
System.out.println(a == b);   // true (misma referencia del pool)
System.out.println(a == c);   // false (referencias distintas)
System.out.println(a.equals(c)); // true (mismo contenido)

Clave: Para comparar texto, usa equals (contenido), no == (referencia).


🧩 Inmutabilidad y por qué importa

  • Inmutable ⇒ cada “cambio” en el String crea otro String.
  • Ventajas: seguridad, hilos, cacheo en el pool, fácil de compartir.
  • Inconveniente: concatenaciones repetidas pueden ser lentas y crear basura de objetos.
// 🔴 Ineficiente en bucles
String s = "";
for (int i = 0; i < 10_000; i++) {
  s += i; // cada vuelta crea un String nuevo, no se modifica el String s, sino que se van creando nuevos
}

// ✅ Mejor con StringBuilder
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10_000; i++) {
  sb.append(i);
}
String s2 = sb.toString();

🧭 Crear y obtener Strings

  • Literales: "Hola" (recomendado).
  • Conversión: String.valueOf(123), Objects.toString(obj).
  • Formato: String.format("Hola %s, tienes %d puntos", nombre, puntos).
  • Join: String.join(", ", "rojo", "verde", "azul");. Concatena varios textos poniendo un separador entre cada uno, sin separador al principio ni al final.
String nombre = "Ada";
int puntos = 42;
String saludo = String.format("Hola %s, tienes %d puntos", nombre, puntos);
String lista = String.join(", ", List.of("rojo", "verde", "azul")); // "rojo, verde, azul"`
List<String> partes = List.of("2025", "10", "15");
String fecha = String.join("-", partes);                // "2025-10-15"

🛠️ Métodos esenciales (con ejemplos)

📚 El operador concatenación +

La clase proporciona el operador + (concatenación) para unir dos o más String. El resultado de aplicar este operador es un nuevo String concatenación de los otros. Por ejemplo, si tenemos dos String b y c:

String b = "Ordenador";
String c = " Portátil";

String

La operación

b = b + c;

Crea un nuevo String que se incluye en el String Pool:

String

📏 Longitud y acceso. Índices

Cada uno de los caracteres que forman un String son del tipo primitivo char. Los caracteres de un string están numerados internamente con índices empezando desde el cero:

String

El primer carácter tiene índice 0 y el último tiene la longitud del string menos 1.

String s = "Hola";
s.length();      // 4
s.charAt(1);     // 'o'

Para recorrer todos los caracteres que forman el String se utiliza un bucle for:

String major = "CSE";
for (int i = 0; i < major.length(); i++) {
  char c = major.charAt(i);
  System.out.println(c);
}
OUTPUT
C
S
E

🔍 Buscar y cortar

String t = "programar en Java";
t.indexOf("Java");        // 13
t.lastIndexOf("a");       // 16
t.contains("en ");        // true
t.startsWith("pro");      // true
t.endsWith("Java");       // true
t.substring(0, 9);        // "programar"

🔡 Mayúsculas / minúsculas / espacios

"  Hola  ".trim();         // "Hola" (quita espacios al principio y al final)
"  Hola  ".strip();        // "Hola" (quita espacios al principio y al final del texto, soporta espacios Unicode)
"\u00A0Hola\u00A0".trim();  // "\u00A0Hola\u00A0" (NO quita Non-Breaking Space)
"\u00A0Hola\u00A0".strip(); // "Hola"             (sí lo quita)
"hola".toUpperCase();      // "HOLA"
"Hola".toLowerCase();      // "hola"
"".isEmpty();              // true
"   ".isBlank();           // true (Java 11+)

🔁 Reemplazar y dividir

"12-34-56".replace("-", ":");   // "12:34:56"
"uno;dos;tres".split(";");      // ["uno", "dos", "tres"]

// ⚠️ split usa REGEX. Para texto literal, o escapamos o:
String[] partes = "a.b.c".split("\\.");  // ["a","b","c"]

📐 Comparar

"Hola".equals("hola");           // false
"Hola".equalsIgnoreCase("hola"); // true
"abc".compareTo("abd");          // < 0 (orden lexicográfico)

🧵 Formateo y plantillas

String msg = String.format("PI: %.2f", Math.PI);  // "PI: 3.14"
System.out.printf("Usuario: %s%n", "Max");        // Impresión formateada

🧪 Unicode, emojis y código seguro

  • Un char es una unidad UTF-16, no siempre un carácter visible.
  • Emojis y algunos símbolos usan pares sustitutos (surrogates).
  • Para recorrer caracteres reales, usa code points:
String s = "A 😄 B";
s.length();              // 5 (porque 😄 usa 2 unidades UTF-16)
int realChars = s.codePointCount(0, s.length()); // 3

s.codePoints().forEach(cp -> {
  System.out.println(Integer.toHexString(cp));
});

🚦 String vs StringBuilder vs StringBuffer

Opción Característica Cuándo usar
String Inmutable, simple, seguro Textos pequeños, concatenaciones puntuales, literales, claves de mapa
StringBuilder Mutable, no sincronizado Concatenaciones en bucle o construcción incremental de texto
StringBuffer Mutable, sincronizado Contextos multi‑hilo muy específicos (raro hoy)

Regla práctica: si concatenas dentro de un bucle o en procesos largos, usa StringBuilder.

StringJoiner Pequeña utilidad para ir añadiendo elementos con separador, prefijo y sufijo.

StringJoiner j = new StringJoiner(", ", "[", "]");
j.add("rojo").add("verde").add("azul"); // "[rojo, verde, azul]"


🧯 Errores típicos (y cómo evitarlos)

  • ❌ Usar == en vez de equals para comparar contenido.
  • ❌ Abusar de + en bucles → usa StringBuilder.
  • split sin escapar: ".", "|", "?" son regex. Usa \\. o Pattern.quote(".").
  • ❌ Confundir replace (literal) con replaceAll (regex).
  • ❌ Asumir que length() es “caracteres visibles” (ojo con emojis).
  • null vs "" (cadena vacía) vs " " (en blanco). Usa isEmpty()/isBlank().
// ✅ Comparación segura null-safe
Objects.equals(cadena1, cadena2); // evita NullPointerException

🧭 ¿Cuándo usar Strings y cuándo no?

Úsalos para…
- Mostrar mensajes, logs, etiquetas y entradas de usuario. - Claves legibles (IDs, códigos) si no hay coste de rendimiento fuerte. - Plantillas y formateo de salida.

Evítalos para…
- Grandes construcciones de texto en bucles → usa StringBuilder. - Datos binarios → usa byte[]. - IDs que necesitan operaciones matemáticas → números/UUID (no String).


📝 Conversión de tipos (parseo y formateo)

// Número → String
String s1 = String.valueOf(1234);   // "1234"

// String → Número
int n = Integer.parseInt("42");     // 42
double d = Double.parseDouble("3.14");

// Con formato localizado (ej.: separadores decimales)
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMANY);
Number x = nf.parse("1.234,56");    // 1234.56 (como double)

🧱 Text Blocks (Java 15+)

Para textos multilínea legibles. Incluye saltos de línea y tabulaciones automáticamente. Las comillas triples de apertura deben ir solas en la línea. El cierre también (con posible indentación).

String html = """
    <html>
      <h1>Hola</h1>
    </html>
    """;

📎 Plantillas útiles

// Normalizar espacios
String normaliza(String s) {
  return Arrays.stream(s.strip().split("\\s+"))
               .collect(Collectors.joining(" "));
}

📌 Conclusión

Los String son fundamentales en Java. Entender inmutabilidad, pool, regex y StringBuilder te ahorra errores y mejora rendimiento. Usa esta hoja como guía rápida y practica los mini‑retos.