¿Cuál es la diferencia entre == y igual () en Java?
Quería aclarar si entendí esto correctamente:
==
es una comparación de referencia, es decir, ambos objetos apuntan a la misma ubicación de memoria.equals()
evalúa la comparación de valores en los objetos
En general, la respuesta a tu pregunta es "sí", pero...
.equals(...)
Sólo comparará lo que está escrito para comparar, ni más ni menos.- Si una clase no anula el método igual, entonces utiliza de forma predeterminada el
equals(Object o)
método de la clase principal más cercana que ha anulado este método. - Si ninguna clase principal ha proporcionado una anulación, entonces se utiliza de forma predeterminada el método de la clase principal principal, Objeto, y por lo tanto te queda el
Object#equals(Object o)
método. Según la API de objetos, esto es lo mismo que==
; es decir, devuelve verdadero si y sólo si ambas variables hacen referencia al mismo objeto, si sus referencias son la misma. Por lo tanto, probará la igualdad de objetos y no la igualdad funcional . - Recuerde siempre anular
hashCode
si anulaequals
para no "romper el contrato". Según la API, el resultado devuelto por elhashCode()
método para dos objetos debe ser el mismo si susequals
métodos muestran que son equivalentes. Lo contrario no es necesariamente cierto.
Con respecto a la clase String:
El método equals() compara el "valor" dentro de las instancias de String (en el montón) independientemente de si las dos referencias de objetos se refieren a la misma instancia de String o no. Si dos referencias de objetos de tipo String se refieren a la misma instancia de String, ¡excelente! Si las dos referencias de objetos se refieren a dos instancias de String diferentes... no hay diferencia. Es el "valor" (es decir: el contenido de la matriz de caracteres) dentro de cada instancia de cadena que se compara.
Por otro lado, el operador "==" compara el valor de dos referencias de objetos para ver si se refieren a la misma instancia de String . Si el valor de ambos objetos hace referencia a la misma instancia de cadena, entonces el resultado de la expresión booleana sería "verdadero"..duh. Si, por otro lado, el valor de ambas referencias de objetos "se refieren a" diferentes instancias de String (aún cuando ambas instancias de String tienen "valores" idénticos, es decir, el contenido de las matrices de caracteres de cada instancia de String es el mismo) el El resultado de la expresión booleana sería "falso".
Como ocurre con cualquier explicación, déjelo asimilar.
Espero que esto aclare las cosas un poco.
Existen algunas pequeñas diferencias dependiendo de si se habla de "primitivos" o de "Tipos de objetos"; lo mismo puede decirse si se habla de miembros "estáticos" o "no estáticos"; también puedes mezclar todo lo anterior...
Aquí hay un ejemplo (puedes ejecutarlo):
public final class MyEqualityTest
{
public static void main( String args[] )
{
String s1 = new String( "Test" );
String s2 = new String( "Test" );
System.out.println( "\n1 - PRIMITIVES ");
System.out.println( s1 == s2 ); // false
System.out.println( s1.equals( s2 )); // true
A a1 = new A();
A a2 = new A();
System.out.println( "\n2 - OBJECT TYPES / STATIC VARIABLE" );
System.out.println( a1 == a2 ); // false
System.out.println( a1.s == a2.s ); // true
System.out.println( a1.s.equals( a2.s ) ); // true
B b1 = new B();
B b2 = new B();
System.out.println( "\n3 - OBJECT TYPES / NON-STATIC VARIABLE" );
System.out.println( b1 == b2 ); // false
System.out.println( b1.getS() == b2.getS() ); // false
System.out.println( b1.getS().equals( b2.getS() ) ); // true
}
}
final class A
{
// static
public static String s;
A()
{
this.s = new String( "aTest" );
}
}
final class B
{
private String s;
B()
{
this.s = new String( "aTest" );
}
public String getS()
{
return s;
}
}
Puede comparar las explicaciones de "==" (Operador de igualdad) y ".equals(...)" (método de la clase java.lang.Object) a través de estos enlaces:
- ==: http://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html
- .equals(...): http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#equals(java.lang.Object)
La diferencia entre ==
y equals
me confundió por algún tiempo hasta que decidí mirarlo más de cerca. Muchos de ellos dicen que para comparar cadenas debes usar equals
y no ==
. Espero que en esta respuesta pueda decir la diferencia.
La mejor manera de responder a esta pregunta será haciéndote algunas preguntas. así que comencemos:
¿Cuál es el resultado del siguiente programa?
String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);
si usted dice,
false
true
Diré que tienes razón , pero ¿ por qué dijiste eso ? y si dices que la salida es,
true
false
Diré que estás equivocado pero aun así te preguntaré, ¿por qué crees que eso es correcto?
Ok, intentemos responder a esta:
¿Cuál es el resultado del siguiente programa?
String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);
Ahora si dices,
false
true
Diré que estás equivocado , pero ¿ por qué está mal ahora ? la salida correcta para este programa es
true
false
Compare el programa anterior e intente pensar en ello.
De acuerdo. Ahora esto podría ayudar (lea esto: imprima la dirección del objeto ; no es posible, pero aún así podemos usarlo).
String mango = "mango";
String mango2 = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(mango3 != mango2);
System.out.println(mango3 == mango2);
// mango2 = "mang";
System.out.println(mango+" "+ mango2);
System.out.println(mango != mango2);
System.out.println(mango == mango2);
System.out.println(System.identityHashCode(mango));
System.out.println(System.identityHashCode(mango2));
System.out.println(System.identityHashCode(mango3));
¿Puedes intentar pensar en el resultado de las últimas tres líneas del código anterior? Para mí, ideone imprimió esto ( puedes consultar el código aquí ):
false
true
true
false
mango mango
false
true
17225372
17225372
5433634
¡Oh! Ahora ves que identidadHashCode(mango) es igual a identidadHashCode(mango2) pero no es igual a identidadHashCode(mango3)
Aunque todas las variables de cadena (mango, mango2 y mango3) tienen el mismo valor, que es "mango", identityHashCode()
todavía no es el mismo para todas.
Ahora intenta descomentar esta línea // mango2 = "mang";
y ejecútala nuevamente, esta vez verás que las tres identityHashCode()
son diferentes. Hmm, esa es una pista útil.
sabemos que si hashcode(x)=N
y hashcode(y)=N
=>x is equal to y
No estoy seguro de cómo funciona Java internamente, pero supongo que esto es lo que sucedió cuando dije:
mango = "mango";
Java creó una cadena "mango"
a la que apuntaba (referenciada) la variable mango
algo como esto
mango ----> "mango"
Ahora en la siguiente línea cuando dije:
mango2 = "mango";
De hecho, reutilizó la misma cadena "mango"
que se parece a esta.
mango ----> "mango" <---- mango2
Tanto mango como mango2 apuntan a la misma referencia. Ahora cuando dije
mango3 = new String("mango")
De hecho, creó una referencia (cadena) completamente nueva para "mango". que se parece a esto,
mango -----> "mango" <------ mango2
mango3 ------> "mango"
y es por eso que cuando publico los valores de mango == mango2
, aparece true
. y cuando puse el valor de mango3 == mango2
, se publicó false
(incluso cuando los valores eran los mismos).
y cuando descomentaste la línea, // mango2 = "mang";
en realidad creó una cadena "mang" que convirtió nuestro gráfico en este:
mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"
Es por eso que el identidadHashCode no es el mismo para todos.
Espero que esto les ayude chicos. En realidad, quería generar un caso de prueba en el que ==
falla y equals()
pasa. No dude en comentar y avíseme si me equivoco.
El operador == prueba si dos variables tienen las mismas referencias (también conocido como puntero a una dirección de memoria) .
String foo = new String("abc");
String bar = new String("abc");
if(foo==bar)
// False (objects are identical but not same)
bar = foo;
if(foo==bar)
// True (Now, objects are identical and same)
Mientras que el método equals() prueba si dos variables se refieren a objetos que tienen el mismo estado (valores) .
String foo = new String("abc");
String bar = new String("abc");
if(foo.equals(bar))
// True (The objects are identical but not same)