Pregunta ¿Cómo comparo cadenas en Java?


He estado usando el == operador en mi programa para comparar todas mis cadenas hasta ahora. Sin embargo, me encontré con un error, cambié uno de ellos a .equals() en cambio, y solucionó el error.

Es == ¿malo? ¿Cuándo debería y no debería ser utilizado? ¿Cual es la diferencia?


727


origen


Respuestas:


== pruebas para la igualdad de referencia (si son el mismo objeto).

.equals() prueba de igualdad de valor (si son lógicamente "iguales").

Objects.equals () cheques para null antes de llamar .equals() por lo que no es necesario (disponible a partir de JDK7, también disponible en Guayaba)

String.contentEquals () compara el contenido de la String con el contenido de cualquier CharSequence (disponible desde Java 1.5).

En consecuencia, si desea probar si dos cadenas tienen el mismo valor, es probable que desee utilizar Objects.equals().

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

Usted casi siempre quiere usarObjects.equals(). En el raro situación donde tu saber estas tratando con internado cuerdas, tú poder utilizar ==.

De JLS 3.10.5. Literales de cuerda:

Además, un literal de cadena siempre se refiere a mismo instancia de clase String. Esto es porque los literales de cadena - o, más generalmente, las cadenas que son los valores de las expresiones constantes (§15.28) - son "internados" para compartir instancias únicas, usando el método String.intern.

Ejemplos similares también se pueden encontrar en JLS 3.10.5-1.


4949



== prueba referencias de objetos .equals() prueba los valores de cadena.

A veces parece como si == compara los valores, porque Java hace algunas cosas detrás de escena para asegurarse de que las cadenas idénticas en línea sean en realidad el mismo objeto.

Por ejemplo:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

¡Pero cuidado con los nulos! 

== maneja null cuerdas bien, pero llamando .equals() desde una cadena nula causará una excepción:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

Entonces si sabes eso fooString1 puede ser nulo, dígale al lector que al escribir

System.out.print(fooString1 != null && fooString1.equals("bar"));

El siguiente es más corto, pero es menos obvio que comprueba nulo (de Java 7):

System.out.print(Objects.equals(fooString1, "bar"));

627



== compara referencias de objetos.

.equals() compara valores de cadena.

A veces == da ilusiones de comparar valores de cadena, como en los siguientes casos:

String a="Test";
String b="Test";
if(a==b) ===> true

Esto se debe a que al crear cualquier literal String, la JVM primero busca ese literal en el grupo de cadenas, y si encuentra una coincidencia, se le dará la misma referencia al nuevo String. Debido a esto, obtenemos:

(a == b) ===> verdadero

                       String Pool
     b -----------------> "test" <-----------------a

Sin embargo, == falla en el siguiente caso:

String a="test";
String b=new String("test");
if (a==b) ===> false

En este caso para new String("test") la declaración nueva cadena se creará en el montón, y esa referencia se le dará a b, asi que b recibirá una referencia en el montón, no en el grupo de cadenas.

Ahora a está apuntando a una cadena en el grupo de cadenas mientras b está apuntando a una Cadena en el montón. Por eso obtenemos:

if (a == b) ===> falso.

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

Mientras .equals() siempre compara un valor de String por lo que da verdadero en ambos casos:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

Entonces usando .equals() siempre es mejor


396



los == el operador verifica si las dos cadenas son exactamente el mismo objeto.

los .equals() método comprobará si las dos cadenas tienen el mismo valor.


203



Las cadenas en Java son inmutables. Eso significa que cada vez que intentes cambiar / modificar la cadena obtendrás una nueva instancia. No puedes cambiar la cadena original. Esto se ha hecho para que estas instancias de cadena se puedan almacenar en caché. Un programa típico contiene una gran cantidad de referencias de cadenas y el almacenamiento en caché de estas instancias puede disminuir la huella de memoria y aumentar el rendimiento del programa.

Cuando se usa == operador para la comparación de cadenas, no se está comparando el contenido de la cadena, sino que se está comparando la dirección de la memoria. Si ambos son iguales, devolverá verdadero y falso en caso contrario. Mientras que igual en cadena compara el contenido de la cadena.

Entonces, la pregunta es si todas las cadenas están en caché en el sistema, ¿cómo es que == devuelve falso mientras que igual devuelve verdadero? Bueno, esto es posible. Si haces una nueva cadena como String str = new String("Testing") terminará creando una nueva cadena en la memoria caché, incluso si la memoria caché ya contiene una cadena con el mismo contenido. En breve "MyString" == new String("MyString") siempre devolverá falso.

Java también habla de la función interna () que se puede usar en una cadena para hacerla parte de la memoria caché, por lo que "MyString" == new String("MyString").intern() volverá verdadero.

Nota: == operador es mucho más rápido que igual solo porque está comparando dos direcciones de memoria, pero necesita estar seguro de que el código no está creando nuevas instancias de cadena en el código. De lo contrario, encontrarás errores.


154



String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

Asegúrate de entender por qué. Es porque el == comparación solo compara referencias; el equals() método hace una comparación carácter por carácter de los contenidos.

Cuando llamas nuevo para a y b, cada uno obtiene una nueva referencia que apunta al "foo" en la tabla de cuerdas. Las referencias son diferentes, pero el contenido es el mismo.


132



Sí, es malo ...

== significa que sus dos referencias de cadena son exactamente el mismo objeto. Es posible que haya escuchado que este es el caso porque Java mantiene una especie de tabla literal (lo que hace), pero ese no es siempre el caso. Algunas cadenas se cargan de diferentes maneras, construidas a partir de otras cadenas, etc., por lo que nunca debe suponer que se almacenan dos cadenas idénticas en la misma ubicación.

Igual hace la comparación real para usted.


114



Sí, == es malo para comparar cadenas (cualquier objeto realmente, a menos que sepa que son canónicas). == solo compara referencias de objetos. .equals() pruebas de igualdad. Para Strings, a menudo serán iguales pero, como has descubierto, eso no siempre está garantizado.


110



Java tiene un grupo de cadenas bajo el cual Java administra la asignación de memoria para los objetos String. Ver String Pools en Java

Cuando verifica (compara) dos objetos usando el == operador compara la igualdad de direcciones en el grupo de cadenas. Si los dos objetos de cadena tienen las mismas referencias de dirección, entonces regresa trueDe lo contrario false. Pero si quiere comparar el contenido de dos objetos String, debe anular el equals método.

equals es en realidad el método de la clase Object, pero se reemplaza en la clase String y se da una nueva definición que compara el contenido del objeto.

Example:
    stringObjectOne.equals(stringObjectTwo);

Pero importa que respete el caso de String. Si quieres comparar mayúsculas y minúsculas, entonces debes elegir el método equalsIgnoreCase de la clase String.

Veamos:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE

104



.equals() compara los datos de una clase (suponiendo que la función esté implementada). == compara las ubicaciones del puntero (ubicación del objeto en la memoria).

== devuelve verdadero si ambos objetos (NO HABLANDO SOBRE PRIMITIVOS) apuntan a la MISMA instancia de objeto. .equals() devuelve verdadero si los dos objetos contienen la misma información equals() Versus == en Java

Eso puede ayudarte.


92



== compara referencias de objetos en Java, y eso no es una excepción para String objetos.

Para comparar los contenidos reales de los objetos (incluidos String), uno debe usar el equals método.

Si una comparación de dos String objetos usando == resulta ser true, eso es porque el String los objetos fueron internados, y la Máquina Virtual de Java tiene múltiples referencias que apuntan a la misma instancia de String. Uno no debe esperar que comparando uno String objeto que contiene los mismos contenidos que otro String objeto que usa == para evaluar como true.


91