¿Cuál es la diferencia entre == y igual () en Java?

Resuelto brainydexter asked hace 13 años • 27 respuestas

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
brainydexter avatar Sep 23 '11 02:09 brainydexter
Aceptado

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 hashCodesi anula equalspara no "romper el contrato". Según la API, el resultado devuelto por el hashCode()método para dos objetos debe ser el mismo si sus equalsmétodos muestran que son equivalentes. Lo contrario no es necesariamente cierto.
Hovercraft Full Of Eels avatar Sep 22 '2011 19:09 Hovercraft Full Of Eels

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.

Jacques Colmenero avatar May 29 '2012 20:05 Jacques Colmenero

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)
Almir Campos avatar Mar 06 '2014 01:03 Almir Campos

La diferencia entre ==y equalsme confundió por algún tiempo hasta que decidí mirarlo más de cerca. Muchos de ellos dicen que para comparar cadenas debes usar equalsy 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)=Ny 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 mangoalgo 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.

govindpatel avatar Apr 05 '2016 10:04 govindpatel

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)
Mohan avatar Aug 09 '2016 14:08 Mohan