Cómo comparar cadenas en Java
Compara cadenas en Java con equals, equalsIgnoreCase, compareTo y evita errores comunes con ==.
Comparar dos valores String en Java es una de las primeras cosas que un principiante hace mal, porque el operador == compara silenciosamente referencias en lugar de contenidos. Este capítulo muestra las formas correctas e idiomáticas de comprobar la igualdad y el orden de las cadenas — equals, equalsIgnoreCase, compareTo y el Objects.equals seguro ante null — y explica exactamente cuándo cada uno es la herramienta adecuada.
Para entender por qué los literales idénticos pueden ser ==, consulta el pool de cadenas; para un recorrido más amplio por las técnicas de comparación, consulta Java string comparison.
Igualdad de contenido con equals
Para comprobar si dos cadenas contienen los mismos caracteres, llama a equals:
String a = "hello";
String b = new String("hello");
boolean same = a.equals(b); // true — same charactersequals recorre las dos secuencias de caracteres y devuelve true solo cuando tienen la misma longitud y los mismos caracteres en el mismo orden. Es el método que necesitas el 99% de las veces que preguntas "¿son estas dos cadenas el mismo texto?".
Un truco defensivo habitual es llamar a equals sobre un literal de cadena para que el receptor nunca sea null:
if ("yes".equals(userInput)) { ... } // safe even if userInput is nullPor qué == es la trampa clásica
== no examina los caracteres en absoluto — pregunta "¿son exactamente el mismo objeto en memoria?". Dado que el compilador interna los literales de cadena (almacena una copia compartida en un pool), dos literales idénticos pueden resultar ser ==, lo que lleva a la gente a pensar que == compara texto. No lo hace: en el momento en que una cadena proviene de new, de la entrada del usuario o de una concatenación en tiempo de ejecución, == devuelve false incluso para texto idéntico.
| Expresión | Resultado | Por qué |
|---|---|---|
"java" == "java" | true | Ambas hacen referencia al mismo literal internado |
"java" == new String("java") | false | new crea un objeto distinto |
"java".equals(new String("java")) | true | Compara contenidos, no identidad |
Regla práctica: nunca uses == para comparar cadenas. Usa equals.
Comparación sin distinción de mayúsculas con equalsIgnoreCase
Cuando las mayúsculas no importan — nombres de usuario, extensiones de archivo, nombres de cabeceras — usa equalsIgnoreCase:
"Java".equalsIgnoreCase("JAVA"); // trueAplica la misma lógica carácter a carácter que equals después de unificar el caso, por lo que "README".equalsIgnoreCase("readme") es true.
Ordenación con compareTo
Para ordenar o clasificar cadenas en lugar de solo comprobar la igualdad, usa compareTo, que devuelve el signo de la diferencia lexicográfica (estilo diccionario):
"apple".compareTo("banana"); // negative — apple comes first
"apple".compareTo("apple"); // 0 — equal
"banana".compareTo("apple"); // positive — banana comes laterUn resultado negativo significa que el receptor va antes que el argumento, 0 significa igual y positivo significa después. Existe una variante compareToIgnoreCase y String.CASE_INSENSITIVE_ORDER para usar como Comparator. Ten en cuenta que el orden predeterminado es por punto de código Unicode, por lo que todas las letras mayúsculas (A–Z) se ordenan antes que todas las letras minúsculas.
Un ejemplo práctico
Este programa ejercita todos los enfoques uno junto al otro para que puedas ver con precisión cómo se comporta cada uno.
Lo que se puede extraer de la ejecución:
a == bimprimefalseaunque ambas cadenas contienen "java", porquenew String("java")es un objeto separado — prueba de que==compara identidad, no texto.a.equals(b)imprimetrue:equalsexamina los caracteres, que es lo que casi siempre se entiende por "la misma cadena".a == cimprimetruesolo porque ambos son literales que comparten un objeto internado — este éxito accidental es exactamente lo que lleva a los principiantes a cometer errores con==.equalsIgnoreCaseimprimetruepara"Java"vs"JAVA", mientras quecompareTodevuelve0para texto idéntico y un signo distinto de cero (-1para apple antes de banana) cuando difieren.Objects.equals(null, "x")imprimefalseen lugar de lanzar una excepción, y el array ordenado imprime[Cherry, apple, banana]— laCmayúscula (punto de código 67) se ordena antes que las letras minúsculas (punto de código 97+).
¿Qué método debo usar?
Elige la comparación según la pregunta que estás respondiendo:
| Quieres saber… | Usa | Notas |
|---|---|---|
| ¿El texto es exactamente igual? | a.equals(b) | La opción predeterminada para la igualdad |
| ¿Igual, ignorando mayúsculas/minúsculas? | a.equalsIgnoreCase(b) | Unifica el caso primero |
¿Igual, pero alguno puede ser null? | Objects.equals(a, b) | Devuelve true para dos null, nunca lanza |
| ¿Cuál es su orden de clasificación? | a.compareTo(b) | Negativo / 0 / positivo |
| ¿Orden de clasificación ignorando mayúsculas? | a.compareToIgnoreCase(b) | O String.CASE_INSENSITIVE_ORDER como Comparator |
Un hábito útil: cuando solo necesitas igualdad, prefiere equals (o Objects.equals cuando null es posible) y nunca compareTo(...) == 0, que hace estrictamente más trabajo. Para explorar los métodos en los que se basan, consulta Java string methods y la clase String.