Clase String en Java: cadenas de caracteres

Debido a que gran parte de la información con la que trabajamos en las aplicaciones es de tipo textual, la clase String en Java se convierte en algo esencial, ya que nos va a permitir manejar cadenas de caracteres de muy diversas formas.

Antes de nada, te comento una curiosidad técnica. Cuando tú creas una variable String, este se almacena en memoria ocupando exactamente el espacio que necesita. Pues bien, lo normal sería pensar que cuando reasignamos a esa variable un valor distinto, se usaría esa misma memoria si el nuevo contenido cabe. Pues no, siempre se desecha el contenido anterior y se vuelve a reservar un espacio nuevo.

String saludo = "Muy buenas";
String nombre = "amigo";
saludo = "Hola, "; // Se desecha el contenido anterior 
                   // y se asigna un nuevo espacio en memoria
saludo += nombre; // Igualmente, se desecha lo que contuviera 
                  // antes saludo, no se añade
System.out.println(saludo); // Escribe 'Hola, amigo'

Igual sucede cuando queremos asignar a una cadena el resultado de una concatenación, se desecha lo que se tuviera antes, aunque pienses que sería más fácil simplemente sumar a la cadena el resto.

Todavía no estás preparado para entender por qué esto se hace así, de forma que lo dejaremos para un artículo posterior. Simplemente tenlo en mente.

En el artículo Cadenas de Caracteres en Java: Bases vimos lo básico sobre el manejo de strings. Ahora que ya que tenemos algo más de conocimientos, vamos a practicar con los métodos más relevantes de esta clase.

Métodos indispensables de la clase String en Java

.charAt(int)

Te permite obtener un carácter específico dentro de una cadena de caracteres.

String saludo = "Hola, encantado de conocerte";
char c = saludo.charAt(0); // c pasa a contener 'H'
// Escribe una coma (posición 4 contando desde el 0)
System.out.println(c + saludo.charAt(4)); 

Ten en cuenta que el primer carácter se considera que está en la posición 0.

.length()

Te va a proporcionar el número de caracteres que forman una cadena.

String saludo = "Hola, encantado de conocerte";
System.out.println(saludo.length()); // Escribe 28

Puedes acceder al último carácter de una cadena de esta forma:

String saludo = "Hola, encantado de conocerte";
// Escribimos el último carácter de saludo
System.out.println(saludo.charAt(length()-1)); 

Con estos métodos, charAt y length, podemos hacer prácticamente todo lo que se debería poder hacer con cadenas de caracteres. Eso sí, tenemos muchos más métodos que nos pueden facilitar el trabajo. De todas formas, te recomiendo que trates de hacer todos los ejercicios de la lista de cadenas solo con charAt y length, de forma que practiques todo lo visto hasta el momento.

Métodos adicionales interesantes por orden alfabético

No voy a incluir todos los métodos de la clase String en Java, pero sí los que yo considero más interesantes para ti como aprendiz de Java.

.compareTo(String)

Compara una cadena con otra lexicográficamente, es decir, carácter a carácter. De esta forma si devuelve un número menor que 1, la cadena es menor, si devuelve 0 igual y si devuelve mayor que 0 la cadena es mayor.

// Devuelve -25
System.out.println("Cadena menor devuelve " + "abc".compareTo("zyx")); 
// Devuelve 0 
System.out.println("Cadena igual devuelve " + "abc".compareTo("abc"));  
// Devuelve 1
System.out.println("Cadena mayor devuelve " + "abd".compareTo("abc")); 

Fíjate en el tercer y último ejemplo en el que la cadena es mayor. La comparación se haría: ‘a’ es igual a ‘a’ por lo que continúo con el siguiente carácter, ‘b’ es igual a ‘b’ con lo que continúo con el siguiente, ‘d’ es mayor que ‘c’, devuelvo mayor.

Nota: Fíjate en los resultados que devuelven esas instrucciones y trata de deducir qué significa más concretamente el número.

El método compareToIgnoreCase es similar a este pero ignora las mayúsculas y las minúsculas.

Por cierto, te recomiendo que te quedes con el nombre de este método, porque va a ser muy importante más adelante.

.contains(CharSequence)

Comprueba si una cadena está contenida dentro de otra, devolviendo true si está y false si no está.

String fin = "a.";
String saludo = "Hola";
// Devuelve true
System.out.println("Hola contiene 'a'" + "Hola".compareTo("a")); 
// Devuelve false
System.out.println("Hola no contiene 'a.' " + saludo.compareTo(fin)); 

Observa que incluimos cadenas de caracteres con comillas dobles y que no estamos restringidos a poner un simple carácter, sino cadenas completas.

.endsWith(String) y startsWidth(String)

Comprueba si una cadena termina o comienza con otra, devolviendo un booleano según el caso.

String fin = "a.";
String saludo = "Hola";
// Devuelve true
System.out.println("Hola termina en 'a'" + "Hola".endsWith("a")); 
// Devuelve false
System.out.println("Hola no termina en 'a.' " + "Hola".endsWith(fin));
// Devuelve true
System.out.println("Hola comienza con 'H' " + saludo.startsWith("H"));

.equals(Object)

Comprueba si un objeto es igual a la cadena que llama al método. Por ahora, aunque hemos dicho que puedes usar un objeto, utiliza sólo cadenas (String).

String fin = "a.";
String saludo = "Hola";
System.out.println("Hola".equals("Hola")); 
System.out.println(saludo.equals(fin)); 

El método equalsIgnoreCase es análogo a equals pero sin tener en cuenta mayúsculas y minúsculas.

.indexOf(String)

Este método busca la primera vez que aparece un string dentro de otro y nos devuelve la posición en la que empieza. Si no lo encuentra devolverá -1.

String fin = "a.";
String saludo = "Hola";
System.out.println("Hola".indexOf("Hola")); // Devuelve 0
System.out.println("Hola".indexOf("a")); // Devuelve 3
System.out.println(saludo.indexOf(fin)); // Devuelve -1

Te recuerdo que la primera posición de una cadena de caracteres se cuenta como 0.

Si después de la cadena que buscas incluyes un número, estás usando el método .indexOf(String,int). Este método empieza a buscar la cadena indicada en la posición que le indicas, por lo que ignora todo lo que haya antes.

String saludo = "Hola amigo";
System.out.println(saludo.indexOf("a",0)); // Devuelve 3
System.out.println(saludo.indexOf("a",4)); // Devuelve 5
System.out.println(saludo.indexOf("a",6)); // Devuelve -1

Algo interesante que puedes hacer, es buscar una cadena a partir de la posición en la que la encontraste anteriormente:

String saludo = "Hola amigo";
// Devuelve 5
System.out.println(saludo.indexOf("a",saludo.indexOf("a",0)+1)); 

Ten en cuenta también que tienes a tu disposición un método similar a este, lastIndexOf, que se comporta de forma totalmente análoga solo que contando desde el final de la cadena.

.isEmpty()

Método simple que devuelve true si y solo si la longitud de la cadena es 0. No te confundas, si no has inicializado la cadena a ningún valor, este método fallará.

.replace(char, char)

Devuelve una cadena en la que se reemplazan todas las ocurrencias de un carácter por el otro carácter. También se puede utilizar con cadenas de caracteres.

String cadena = "Esto es una cadena de caracteres";
// Escribe Esto_es_una_cadena_de_caracteres
System.out.println(cadena.replace(" ", "_")); 

Ojo, si quieres que el contenido de tu cadena se vea modificado tendrás que utilizar una instrucción de asignación.

String cadena = "Esto es una cadena de caracteres";
// Escribe Esto_es_una_cadena_de_caracteres
System.out.println(cadena.replace(" ", "_")); 
// Cadena no ha cambiado
System.out.println(cadena); 
cadena =  cadena.replace(" ", "_"); 
// Ahora sí ha cambiado
System.out.println(cadena); 

.substring(int,int)

Obtiene una subcadena de la cadena original que incluye desde el primer carácter especificado mediante su posición, hasta el último carácter indicado, que por cierto no se incluye.

String cadena = "Esto es una cadena de caracteres";
// Escribe "es una cad"
System.out.println(cadena.substring(5,15));
// Escribe "acteres"
System.out.println(cadena.substring(25));

Como has visto en el ejemplo, si únicamente especificas un número se forma la subcadena desde la posición indicada hasta el final de la cadena original.

.toLowerCase() y .toUpperCase

Retornan una cadena en la que se pasan todos los caracteres de original a minúsculas y a mayúsculas respectivamente.

String cadena = "Esto Es Una Cadena";
// Escribe "esto es una cadena"
System.out.println(cadena.toLowerCase());
// Escribe "ESTO ES UNA CADENA"
System.out.println(cadena.toUpperCase());

Resumen sobre la clase String en Java

Aunque como dijimos al principio con .length() y .charAt(int) podríamos obtener los mismos resultados que con el resto de métodos que hemos visto, sería una tarea bastante laboriosa y por eso mismo existen estos últimos.

Otra cosa que debes observar y no pasar por alto es que los métodos que hemos visto para hacer cambios sobre la cadena, en realidad no modifican la cadena original, sino que devuelven una nueva cadena con el resultado, por lo que si queremos que nuestro string se vea modificado tendremos que hacerlo mediante una sentencia de asignación.

No hemos visto métodos importantes como matches y el resto de los que trabajan con expresiones regulares, porque tampoco hemos visto expresiones regulares. Ya llegará el momento.