Cadenas: trabajar con texto
En resumen: Una cadena (string) es texto, una secuencia de caracteres con índices desde 0: tiene una longitud y métodos para buscar, reemplazar, recortar, dividir en partes y comparar.
Problema
El código es correcto, pero no funciona
La tienda da un 10% de descuento con el código VERANO10. Una clienta lo copia del anuncio, pero lo escribe en minúsculas y sin querer pone un espacio delante:
Scanner in = new Scanner(System.in);String code = in.nextLine();if (code.equals("VERANO10")) { System.out.println("10% de descuento");} else { System.out.println("Código no válido");} verano10Código no válidoPara una persona, el código es el mismo. Para el programa, verano10 y VERANO10 son textos distintos: el primero tiene un carácter más, y las letras son otras. Tienes que poder mirar dentro de un texto y arreglarlo.
La idea
El texto es una secuencia de caracteres
El texto son caracteres colocados uno detrás de otro: letras, cifras, espacios, signos. Cada carácter tiene un índice, como en un array. El primero tiene el índice 0.
String code = "VERANO10";System.out.println(code.length());System.out.println(code.charAt(0));System.out.println(code.charAt(code.length() - 1));8V0code.length()es el número de caracteres.code.charAt(0)es el carácter con índice 0. El último carácter tiene el índicelength() - 1.
Un solo carácter tiene su propio tipo: char. Se escribe entre comillas simples: 'V', '0', ' '. El texto va entre comillas dobles: "V" es un texto con un carácter, no un char.
Cuidado con los paréntesis: en el texto es length(), con paréntesis, porque es un método. En el array es length, sin paréntesis.
Míralo
Carácter a carácter
¿Cuántas cifras tiene el número de teléfono? Recorres los índices desde 0 hasta el último y miras cada carácter:
String phone = "0888 123 456";int digits = 0;for (int i = 0; i < phone.length(); i++) { char c = phone.charAt(i); if (c >= '0' && c <= '9') { digits++; }}System.out.println("Cifras: " + digits);Cifras: 10c >= '0' && c <= '9' funciona porque cada carácter es en realidad un número: su código en la tabla de caracteres. Las cifras de '0' a '9' tienen códigos seguidos, y también las letras de 'a' a 'z'. Por eso los caracteres se comparan como números.
Más precisamente, para curiosos
- Para comprobaciones así hay métodos ya hechos:
Character.isDigit(c),Character.isLetter(c),Character.isUpperCase(c),Character.isLowerCase(c). También conocen letras que no están en el alfabeto inglés, comoéoñ. - El código de un carácter se obtiene con una conversión:
(int) 'A'es 65. Al revés,(char) 66es'B'. Por eso'a' + 1es el número 98, no la letrab. - Sin índice:
for (char c : phone.toCharArray())recorre los caracteres, igual que for-each recorre un array.
Pruébalo
¿Qué carácter?
¿Qué imprimirá el programa?
String word = "Factura";System.out.println(word.charAt(3));System.out.println(word.length());Los índices son F 0, a 1, c 2, t 3. El carácter con índice 3 es el cuarto: «t». La longitud es el número de todos los caracteres, 7. El último índice es 6.
La idea
Los métodos del texto
El texto trae métodos ya hechos: acciones que llamas con un punto después del texto. Este es el arreglo del código promocional:
String code = " verano10";String clean = code.trim().toUpperCase();System.out.println("[" + clean + "]");System.out.println(clean.equals("VERANO10"));[VERANO10]truetrim() quita los espacios del principio y del final. toUpperCase() pone todas las letras en mayúscula. Los métodos se pueden encadenar uno tras otro: el primero devuelve un texto, y el segundo se llama sobre él.
Algunos más, sobre una dirección de correo:
String email = "lucia.garcia@correo.es";System.out.println(email.contains("@"));System.out.println(email.indexOf("@"));System.out.println(email.substring(0, email.indexOf("@")));System.out.println(email.replace(".", " "));System.out.println(email.endsWith(".es"));true12lucia.garcialucia garcia@correo estrue| Método | Qué hace |
|---|---|
contains(x) |
si x está dentro |
indexOf(x) |
el índice donde aparece x por primera vez (-1 si no está) |
substring(a, b) |
una parte del texto |
replace(x, y) |
cada x se reemplaza por y |
startsWith(x), endsWith(x) |
si empieza (termina) por x |
toLowerCase() |
todas las letras en minúscula |
Más precisamente, para curiosos
substring(a, b) toma los caracteres desde el índice a hasta el índice b, sin b. Son b - a caracteres. Con un solo argumento toma todo hasta el final:
String date = "2026-10-24";System.out.println(date.substring(5, 7));System.out.println(date.substring(8));1024La idea
El texto no cambia
Hay una particularidad que al principio confunde a todo el mundo:
String name = "maria";name.toUpperCase();System.out.println(name);name = name.toUpperCase();System.out.println(name);mariaMARIALa segunda línea no hace nada visible. toUpperCase() no cambia name. Crea un texto nuevo en mayúsculas y lo devuelve. Nadie lo guarda, y se pierde.
Una vez creado, un texto no se puede cambiar. Se dice que es inmutable (immutable). Cada método que «cambia» un texto en realidad devuelve uno nuevo. Para guardarlo, lo asignas: name = name.toUpperCase();.
String name = "maria";name.toUpperCase();System.out.println(name);name = name.toUpperCase();System.out.println(name);Paso a paso, en palabras
- name guarda el texto «maria»: 5 caracteres con índices del 0 al 4.
- toUpperCase() no toca «maria». Crea un texto nuevo, «MARIA».
- Nadie guarda el texto nuevo, y se pierde.
- name sigue guardando «maria», y eso es lo que se imprime.
- Otro texto nuevo, «MARIA», pero ahora = lo guarda en name. El antiguo «maria» se descarta.
- Ahora name guarda «MARIA».
Más precisamente, para curiosos
- Por eso
+=sobre un texto en un bucle largo es lento: cada vuelta crea un texto nuevo y copia todo lo anterior. Para cientos de miles de añadidos existeStringBuilder, un objeto que sí se puede cambiar. Lo veremos en el módulo «Texto y archivos».
Pruébalo
Encuentra el error
La usuaria escribe su correo con mayúsculas y espacios. El programa debería limpiarlo y dejarla entrar, pero dice «No existe ese usuario.». ¿En qué línea está el error?
Elige la línea con el error.
email.trim(); devuelve un texto nuevo sin los espacios, pero no se guarda en ningún sitio. email sigue teniendo los espacios. La corrección es email = email.trim();, igual que en la línea 2.
La idea
El texto en partes
A menudo un texto guarda varias cosas separadas por un signo: productos con una coma, palabras con un espacio. split lo divide en partes y devuelve un array de textos:
String list = "leche,pan,huevos,queso";String[] items = list.split(",");System.out.println("Productos: " + items.length);for (int i = 0; i < items.length; i++) { System.out.println((i + 1) + ". " + items[i]);}Productos: 41. leche2. pan3. huevos4. quesoEl separador no forma parte de los trozos. A partir de aquí trabajas con un array normal: longitud, índices, un bucle.
Así también se lee una línea entera de números desde el teclado: la divides y conviertes cada parte en un número. Es justo lo que te faltaba en la lección anterior, la de las tablas:
Scanner in = new Scanner(System.in);String[] parts = in.nextLine().split(" ");int sum = 0;for (String p : parts) { sum += Integer.parseInt(p);}System.out.println(sum);42 38 51 47 60238Más precisamente, para curiosos
splitrecibe una expresión regular, no texto normal. La mayoría de los signos funcionan tal cual, pero.significa «cualquier carácter»: para un punto, escribesplit("\\."). Las expresiones regulares llegan en el módulo «Texto y archivos».- Dos espacios seguidos dan una parte vacía
""entre ellos.split(" +")(uno o más espacios) lo resuelve. - Lo contrario de
splitesString.join(", ", items): une las partes con un separador.
Pruébalo
¿== o equals?
En la primera tarjeta el código promocional se comparaba con equals. ¿Por qué no con ==, como los números? La entrada es admin:
¿Qué imprimirá el programa?
Scanner in = new Scanner(System.in);String user = in.nextLine();System.out.println(user == "admin");System.out.println(user.equals("admin"));Con textos, == no compara las letras. Comprueba si los dos lados son un mismo objeto en memoria. El texto leído del teclado es un objeto nuevo, y "admin" en el código es otro. Las letras son las mismas, los objetos no. equals compara las letras y dice true.
La regla: en Java siempre comparas texto con equals. Si las mayúsculas y minúsculas no importan, usa equalsIgnoreCase.
Más precisamente, para curiosos
A veces == «funciona»: "admin" == "admin" es true, porque Java guarda los textos iguales del código en un solo objeto. Por eso el error pasa una prueba con texto escrito en el código y solo aparece con una entrada real. No te fíes de eso.
Ejercicio
Nombres y palabras
Resuelve los ejercicios en tu editor. El texto se lee del teclado como una línea entera.
1. El nombre al revés. Lee un nombre e imprímelo de atrás hacia delante. Recorres los índices desde el último hasta 0 y añades los caracteres a un texto nuevo.
CarmennemraC2. Número de palabras. Lee una frase y cuenta las palabras. Entre las palabras puede haber más de un espacio, y puede haber espacios al principio y al final. Pista: una palabra empieza donde el carácter no es un espacio y el anterior sí lo es (o no hay ninguno antes).
Hoy es un día festivoPalabras: 53. Palíndromo. Un palíndromo se lee igual de delante hacia atrás que de atrás hacia delante. Los espacios y las mayúsculas no cuentan. Quita los espacios, pon las letras en minúscula y compara el primer carácter con el último, el segundo con el penúltimo, y así sucesivamente.
Anita lava la tinaEs un palíndromoPan con quesoNo es un palíndromoEjercicio
Comprobaciones y conteo
4. Contraseña segura. Pide una contraseña hasta que el usuario escriba una segura: al menos 8 caracteres, al menos una cifra, una mayúscula y una minúscula. Después de cada contraseña débil, di qué se pide. Pista: do-while y una comprobación de cada carácter con Character.isDigit, Character.isUpperCase, Character.isLowerCase.
cafecafe2026Cafe2026Contraseña:Contraseña débil: al menos 8 caracteres, una cifra, una mayúscula y una minúscula.Contraseña:Contraseña débil: al menos 8 caracteres, una cifra, una mayúscula y una minúscula.Contraseña:Contraseña aceptada.Más ejercicios
- Comas en vez de espacios. Lee una frase y reemplaza cada espacio por una coma.
Mañana nos vamos a Valencia→Mañana,nos,vamos,a,Valencia. - El nombre más largo. Lee nombres separados por comas e imprime el más largo.
Ana,Cristina,Pedro→Cristina. - Las vocales con asterisco. Reemplaza cada vocal (a, e, i, o, u) por
*, sea mayúscula o minúscula.Me gusta leer→M* g*st* l**r. - Frecuencia de las letras. Cuenta cuántas veces aparece cada letra en el texto, sin distinguir mayúsculas y minúsculas. Pista: un array de 26 contadores, uno para cada letra de
'a'a'z'(lañy las vocales con tilde quedan fuera de ese rango: de momento puedes no contarlas). El índice de la letracesc - 'a'. Imprime solo las letras que aparecen. - Gráfico de caracteres. Como el ejercicio anterior, pero en lugar del número imprime esa cantidad de asteriscos:
a: ****. - Cuántas veces cada palabra. Lee una frase y, para cada palabra distinta, imprime cuántas veces aparece. Pista: divídela en palabras y, para cada palabra, comprueba si ya se contó antes en el array.
- Ordenar por longitud. Lee palabras separadas por espacios e imprímelas de la más corta a la más larga. Ordena el array como ordenabas números, pero compara las longitudes.
- Número de oraciones. Cuenta las oraciones de un texto: cada una termina con
.,!o?. Cuidado con...y?!: terminan una oración, no tres. - Paréntesis equilibrados. Comprueba si los paréntesis de un texto están equilibrados. Con un solo tipo de paréntesis basta un contador:
(suma 1,)resta 1. El contador nunca debe bajar de 0, y al final debe ser 0. Con tres tipos,(),[],{}, necesitas un array de caracteres donde guardas los paréntesis abiertos, y un contador de hasta dónde está lleno: en un paréntesis de cierre, el último abierto tiene que ser del mismo tipo.{[()]}está equilibrado,([)]no.
Test
Ponte a prueba
Lecciones relacionadas
Sección «Lecciones relacionadas»- Se basa en: Operadores y aritmética · Condiciones · Bucles · Arrays
- Continúa en: Lanzar excepciones y crear las tuyas · Cadenas · Expresiones regulares · Expresiones regulares: grupos y reemplazo
- Ejercicios sobre el tema: Fundamentos del lenguaje