Aprende a comparar Strings con una visión muy práctica.

Hoy te voy a explicar una de las operaciones mas habituales dentro del lenguaje java: comparar dos strings en java. Para ello utilizaré como base un ejemplo sencillo, pero a la vez muy ilustrativo, donde podrás comprobar que en la comparación de cadenas, el resultado no siempre es el que podríamos esperar en un principio. Si deseas adquirir una mayor comprensión de la clase String te invito a que sigas leyendo.

¿Cómo puedes comparar dos Strings en Java?

Existen diferentes formas de comparar dos cadenas de texto dentro de Java. En el siguiente ejemplo te enseño las que he considerado mas importantes. En cada ejemplo puedes ver un tipo de comportamiento distinto. A continuación, deseo que leas el código y pienses cual podría ser el resultado de cada una de las comparaciones. También puedes copiar el código, pegarlo en tu entorno de desarrollo integrado y ejecutarlo.

package com.programarenjava.tutorialbasico;

public class CompararStrings {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		String programarEnJava = "ProgramarEnJava";
		String programarEnJavaObjeto = new String("programarEnJava");
		String programarEnJavaConEspacioEnBlanco = new String(" ProgramarEnJava");

		System.out.println("Caso1: "+("ProgramarEnJava"==programarEnJava));

		System.out.println("Caso2: "+("ProgramarEnJava"==programarEnJavaObjeto));

		System.out.println("Caso3: "+programarEnJava.equals(programarEnJavaObjeto));

		System.out.println("Caso4: "+programarEnJava.compareTo(programarEnJavaObjeto));

		System.out.println("Caso5: "+programarEnJava.compareToIgnoreCase(programarEnJavaObjeto));

		System.out.println("Caso6: "+programarEnJava.equalsIgnoreCase(programarEnJavaConEspacioEnBlanco));

		System.out.println("Caso7: "+programarEnJava.compareTo(programarEnJavaConEspacioEnBlanco));

	}

}

El código de arriba te ofrece 7 ejemplos donde se comparan 2 Strings. Quizás te preguntes, el porqué de tantas formas de hacer lo mismo, y la respuesta es que la forma de comparar ambos literales no está siendo el mismo en cada caso. Por ello, en los siguientes apartados te explico como está funcionando la comparación de cadenas en cada una de las situaciones.

Caso1: Comparando un String constante contra un String constante utilizando el operador de comparación.

Aquí tenemos la comparación mas sencilla y, a la vez, mas intuitiva de Java, la comparación de constantes.  Es muy importante que tengas en mente que el operador == lo que está comparando son direcciones de memoria. (si vienes de otros lenguajes estilo C habrás oido hablar de los punteros, sino, te dejo un enlace a la wikipedia).

Estas cadenas constantes (realmente conocidos como Strings Inmutables) tienen una dirección de memoria única y siempre es la misma mientras el programa está en ejecución. Entonces, al comparar 2 direcciones de memoria que apuntan al mismo String Inmutable, lo que estamos haciendo es comparar una dirección de memoria consigo misma y por ello obtenemos un resultado booleano cierto. (true).

Caso2: Comparando un String constante contra un Objeto de tipo String utilizando el operador de comparación.

En el segundo ejemplo estamos haciendo lo mismo: comparar dos direcciones de memoria.  Sin embargo, mientras que en el lado izquierdo tenemos una cadena constante, en el lado derecho tenemos una instancia de la clase String. ¿Cuál es la diferencia?. El objeto java está almacenado en el espacio de memoria para objetos mientras que el String inmutable está guardado en una zona especial para este tipo de elementos.

Esto ya es suficiente para que comprendas que las direcciones de memoria serán distintas, y por lo tanto, si las comparas obtendrás  un resultado falso (false).

Este tipo de preguntas suelen aparecer en los examenes de certificacion y también en el mundo real. La comparación de Strings es una de las operaciones que mas se utilizan en los programas Java, y mas si cabe en los que utilizan los estandares JEE y frameworks Web (J2EE, JSF, Struts, Spring MVC). Lo digo porque comprender como funcionan los Strings en Java y concretamente cómo hacer comparaciones entre ellos es fundamental si deseas aprender a programar como un profesional.

Caso3: Comparando un String constante contra un Objeto de tipo String utilizando el método equals.

En este caso estamos el método equals de la clase String.  Esta función compara el contenido, carácter a caracter, del String dueño del método frente a otro String que recibe como parámetro.

Esta forma de comparar cadenas es la correcta, sin embargo, puedes llevarte alguna sorpresa ya que este método si distingue entre mayúsculas y minúsculas. Esto quiere decir que para el no es lo mismo el caracter “P” que el carácter “p”. Aquí tienes que pensar que un carácter se codifica como un código y equals internamente compara códigos y no el significado del caracter.

Caso4: Comparando un String constante contra un Objeto de tipo String utilizando el método compareTo.

Además de equals existe otro método que permite comparar dos cadenas. Se trata de compareTo y si te has fijado en el resultado que devuelve te habrás dado cuenta que este es numérico. ¿Qué sentido tiene esto?.

Cuando utilizamos compareTo no solo lo hacemos con la intención de saber si dos Strings son iguales o distintos, sino que además deseamos saber cual de los dos es mayor. Un ejemplo práctico podría ser utilizar este método dentro de un algortimo de ordenación.

Respecto al resultado obtenido, es importante que sepas que un número negativo quiere decir que el String contenido en la variable programarEnJava es menor que el String contenido en la variable programarEnJavaObjeto (Ten siempre en cuenta que cada carácter tiene asociado un código númerico).

Finalmente comentarte compareTo no es un método propio de la clase String, sino que se ha definido en el interfaz java.langComparable. A continuación te dejo un enlace a la documentación oficial sobre dicho interfaz.

Caso5: Comparando un String constante contra un Objeto de tipo String utilizando el método compareToIgnoreCase.

Como ya hemos comentado en los apartados anteriores, los métodos equals y compareTo hacen distinción entre mayúsculas y minúsculas. Por ejemplo, “ProgramarEnJava” no es lo mismo que “programarenjava”. Hay ocasiones en que este comportamiento no es suficiente, por ejemplo, piensa en un buscador por nombre donde solo buscase los nombres que estuvieran escritos con el mismo número de mayúsculas y minúsculas.  Para ti, al igual que para mi, no sería cómodo y por ello la clase String nos ofrece el método comparteToIgnoreCase cuya función es justamente esa, considerar a todos los literales de una palabra como si fueran la misma.

Volviendo al ejemplo puedes apreciar como el resultado es 0. Esto quiere decir que ambas cadenas son idénticas y, sin duda, este método (lo mismo que equalsIgnoreCase) son la solución adecuada cuando pretendas comparar Strings que puedan tener alguna diferencia a nivel de caracter entre mayúscula y minúscula.

Caso6: Comparando un String constante contra un Objeto de tipo String que contiene espacios en blanco utilizando el método equalsIgnoreCase.

En este ejemplo aparece una nueva carácteristica muy común en las comparaciones de Strings en java. Te hablo de comparar dos cadenas que son iguales pero que una de ellas tiene algún espacio en blanco, ya sea al principio o al final de la misma.

Imagina por un momento un formulario web donde el usuario puede introducir su nombre y contraseña. Sin darse cuenta podría introducir algún espacio en blanco. Te pido que sigas imaginando y que pienses en una clase java que se encarga de leer los datos que escribe el usuario. El resultado sería que esta clase terminaría recogiendo esos datos en objetos String, los cuales contendrían molestos espacios en blanco que podrían provocar resultados no esperados al realizar comparaciones.

Esto es justo lo que ocurre en el ejemplo. Al realizar la comparación utilizando equalsIgnoreCase nos estamos protegiendo de las mayúsculas y menúsculas pero no de los espacios en blanco.

Caso7: Comparando un String constante contra un Objeto de tipo String que contiene espacios en blando utilizando el método compareTo.

Este último caso refleja la misma anomalía que el anterior aunque utilizando el método compareTo. La única diferencia es que esta vez nos indica que la variable programarEnJava es mayor que la variable programarEnJavaConEspacioEnBlanco.

Existe diferentes soluciones para arreglar este problema. En un próximo artículo te voy a ofrecer una solución elegante y a la vez comprensible que me servirá para enseñarte que es un interfaz, cómo definirlo y utilizarlo para resolver un problema real.

Hasta aquí este mini-tutorial de cómo se pueden comparar dos Strings en java. Si te ha parecido un artículo interesante y estás pensado en algún conocido a quién podría serle de utilidad no dudes en compartirlo con el. Si tienes alguna duda o sugerencia y te gustaría transmitírmela en privado puedes hacerlo a través del formulario de contacto.

¿Qué otros tipos de comparaciones de Strings te habías encontrado antes?