Comparación de cadenas en Java

1. Información general

En este artículo, hablaremos sobre las diferentes formas de comparar cadenas en Java.

Como String es uno de los tipos de datos más utilizados en Java, esta es, naturalmente, una operación muy utilizada.

2. Cadena Con la comparación de cadena Clase

2.1. Uso del operador de comparación "=="

El uso del operador "==" para comparar valores de texto es uno de los errores más comunes que cometen los principiantes de Java. Esto es incorrecto porque “==” solo verifica la igualdad referencial de dos cadenas , es decir , si hacen referencia al mismo objeto o no.

Veamos un ejemplo de este comportamiento:

String string1 = "using comparison operator"; String string2 = "using comparison operator"; String string3 = new String("using comparison operator"); assertThat(string1 == string2).isTrue(); assertThat(string1 == string3).isFalse();

En el ejemplo anterior, la primera afirmación es verdadera porque las dos variables apuntan al mismo literal de cadena .

Por otro lado, la segunda afirmación es falsa porque string1 se crea con un literal y string3 se crea usando el nuevo operador; por lo tanto, hacen referencia a diferentes objetos.

2.2. Usando igual ()

La clase String anula el equals () heredado de Object. Este método compara dos cadenas carácter por carácter, ignorando su dirección.

Los considera iguales si tienen la misma longitud y los caracteres están en el mismo orden:

String string1 = "using equals method"; String string2 = "using equals method"; String string3 = "using EQUALS method"; String string4 = new String("using equals method"); assertThat(string1.equals(string2)).isTrue(); assertThat(string1.equals(string4)).isTrue(); assertThat(string1.equals(null)).isFalse(); assertThat(string1.equals(string3)).isFalse();

En este ejemplo, las variables cadena1, cadena2 y cadena4 son iguales porque tienen el mismo caso y valor independientemente de su dirección.

Para string3 el método devuelve falso, ya que distingue entre mayúsculas y minúsculas.

Además, si alguna de las dos cadenas es nula , el método devuelve falso.

2.3. Usando equalsIgnoreCase ()

El método equalsIgnoreCase () devuelve un valor booleano. Como sugiere el nombre, este método ignora el uso de mayúsculas y minúsculas en los caracteres al comparar cadenas :

String string1 = "using equals ignore case"; String string2 = "USING EQUALS IGNORE CASE"; assertThat(string1.equalsIgnoreCase(string2)).isTrue();

2.4. Usando compareTo ()

El método compareTo () devuelve un valor de tipo int y compara dos cadenas carácter por carácter lexicográficamente basándose en un diccionario o en un orden natural.

Este método devuelve 0 si dos cadenas son iguales o si ambas son nulas, un número negativo si la primera cadena viene antes del argumento y un número mayor que cero si la primera cadena viene después del argumento .

Veamos un ejemplo:

String author = "author"; String book = "book"; String duplicateBook = "book"; assertThat(author.compareTo(book)) .isEqualTo(-1); assertThat(book.compareTo(author)) .isEqualTo(1); assertThat(duplicateBook.compareTo(book)) .isEqualTo(0);

2.5. Usando compareToIgnoreCase ()

El compareToIgnoreCase () es similar al método anterior, excepto que ignora el caso:

String author = "Author"; String book = "book"; String duplicateBook = "BOOK"; assertThat(author.compareToIgnoreCase(book)) .isEqualTo(-1); assertThat(book.compareToIgnoreCase(author)) .isEqualTo(1); assertThat(duplicateBook.compareToIgnoreCase(book)) .isEqualTo(0);

3. Clase de comparación de cadenas con objetos

Objects es una clase de utilidad que contiene un método estático equals () , útil en este escenario: para comparar dos cadenas.

El método devuelve verdadero si dos cadenas son iguales comparándolas primero usando su dirección, es decir, " ==" . En consecuencia, si ambos argumentos son nulos , devuelve verdadero y si exactamente un argumento es nulo , devuelve falso.

De lo contrario, simplemente llama al método equals () de la clase de tipo del argumento pasado, que en nuestro caso es el método equals () de la clase String . Este método distingue entre mayúsculas y minúsculas porque llama internamente al método equals () de la clase String .

Probemos esto:

String string1 = "using objects equals"; String string2 = "using objects equals"; String string3 = new String("using objects equals"); assertThat(Objects.equals(string1, string2)).isTrue(); assertThat(Objects.equals(string1, string3)).isTrue(); assertThat(Objects.equals(null, null)).isTrue(); assertThat(Objects.equals(null, string1)).isFalse();

4. Comparación de cadenas con Apache Commons

La biblioteca Apache Commons contiene una clase de utilidad llamada StringUtils para String- operaciones conexas ; esto también tiene algunos métodos muy beneficiosos para la comparación de cadenas .

4.1. Usando equals () y equalsIgnoreCase ()

El método equals () de la clase StringUtils es una versión mejorada del método de la clase String equals (), que también maneja valores nulos:

assertThat(StringUtils.equals(null, null)) .isTrue(); assertThat(StringUtils.equals(null, "equals method")) .isFalse(); assertThat(StringUtils.equals("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equals("equals method", "EQUALS METHOD")) .isFalse();

El método equalsIgnoreCase () de StringUtils devuelve un valor booleano . Esto funciona de manera similar a equals (), excepto que ignora las mayúsculas y minúsculas de los caracteres en Strings:

assertThat(StringUtils.equalsIgnoreCase("equals method", "equals method")) .isTrue(); assertThat(StringUtils.equalsIgnoreCase("equals method", "EQUALS METHOD")) .isTrue();

4.2. Usando equalsAny () y equalsAnyIgnoreCase ()

El primer argumento del método equalsAny () es un String y el segundo es un CharSequence de tipo multi-args . El método devuelve verdadero si alguna de las otras cadenas dadas coincide con la primera cadena de forma sensible.

De lo contrario, se devuelve falso:

assertThat(StringUtils.equalsAny(null, null, null)) .isTrue(); assertThat(StringUtils.equalsAny("equals any", "equals any", "any")) .isTrue(); assertThat(StringUtils.equalsAny("equals any", null, "equals any")) .isTrue(); assertThat(StringUtils.equalsAny(null, "equals", "any")) .isFalse(); assertThat(StringUtils.equalsAny("equals any", "EQUALS ANY", "ANY")) .isFalse();

El método equalsAnyIgnoreCase () funciona de manera similar al método equalsAny () , pero también ignora el uso de mayúsculas y minúsculas :

assertThat(StringUtils.equalsAnyIgnoreCase("ignore case", "IGNORE CASE", "any")).isTrue();

4.3. Usando compare () y compareIgnoreCase ()

El método compare () en la clase StringUtils es una versión segura para nulos del método compareTo () de la clase String y maneja valores nulos al considerar un valor nulo menor que un valor no nulo . Dos valores nulos se consideran iguales.

Además, este método se puede utilizar para ordenar una lista de cadenas con entradas nulas :

assertThat(StringUtils.compare(null, null)) .isEqualTo(0); assertThat(StringUtils.compare(null, "abc")) .isEqualTo(-1); assertThat(StringUtils.compare("abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compare("bbc", "abc")) .isEqualTo(1);

El método compareIgnoreCase () se comporta de manera similar, excepto que ignora el uso de mayúsculas y minúsculas :

assertThat(StringUtils.compareIgnoreCase("Abc", "bbc")) .isEqualTo(-1); assertThat(StringUtils.compareIgnoreCase("bbc", "ABC")) .isEqualTo(1); assertThat(StringUtils.compareIgnoreCase("abc", "ABC")) .isEqualTo(0);

Los dos métodos también se pueden utilizar con una opción nullIsLess . Este es un tercer argumento booleano que decide si los valores nulos deben considerarse menores o no .

Un valor nulo es menor que otro String si nullIsLess es verdadero y mayor si nullIsLess es falso.

Probémoslo:

assertThat(StringUtils.compare(null, "abc", true)) .isEqualTo(-1); assertThat(StringUtils.compare(null, "abc", false)) .isEqualTo(1);

El método compareIgnoreCase () con un tercer argumento booleano funciona de manera similar, excepto al ignorar el caso.

5. Conclusión

En este tutorial rápido, discutimos diferentes formas de comparar cadenas.

Y, como siempre, el código fuente de los ejemplos se puede encontrar en GitHub.