What is the difference between == vs equals() in J

2018-12-30 22:47发布

I wanted to clarify if I understand this correctly:

  • == -> is a reference comparison, i.e. both objects point to the same memory location
  • .equals() -> evaluates to the comparison of values in the objects

Am I correct in my understanding ?

标签: java
22条回答
千与千寻千般痛.
2楼-- · 2018-12-30 23:09

There are some small differences depending whether you are talking about "primitives" or "Object Types"; the same can be said if you are talking about "static" or "non-static" members; you can also mix all the above...

Here is an example (you can run it):

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;
    }

}

You can compare the explanations for "==" (Equality Operator) and ".equals(...)" (method in the java.lang.Object class) through these links:

查看更多
看淡一切
3楼-- · 2018-12-30 23:11

The difference between == and equals confused me for sometime until I decided to have a closer look at it. Many of them say that for comparing string you should use equals and not ==. Hope in this answer I will be able to say the difference.

The best way to answer this question will be by asking a few questions to yourself. so let's start:

What is the output for the below program:

String mango = "mango";
String mango2 = "mango";
System.out.println(mango != mango2);
System.out.println(mango == mango2);

if you say,

false
true

I will say you are right but why did you say that? and If you say the output is,

true
false

I will say you are wrong but I will still ask you, why you think that is right?

Ok, Let's try to answer this one:

What is the output for the below program:

String mango = "mango";
String mango3 = new String("mango");
System.out.println(mango != mango3);
System.out.println(mango == mango3);

Now If you say,

false
true

I will say you are wrong but why is it wrong now? the correct output for this program is

true
false

Please compare the above program and try to think about it.

Ok. Now this might help (please read this : print the address of object - not possible but still we can use it.)

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));

can you just try to think about the output of the last three lines in the code above: for me ideone printed this out (you can check the code here):

false
true
true
false
mango mango
false
true
17225372
17225372
5433634

Oh! Now you see the identityHashCode(mango) is equal to identityHashCode(mango2) But it is not equal to identityHashCode(mango3)

Even though all the string variables - mango, mango2 and mango3 - have the same value, which is "mango", identityHashCode() is still not the same for all.

Now try to uncomment this line // mango2 = "mang"; and run it again this time you will see all three identityHashCode() are different. Hmm that is a helpful hint

we know that if hashcode(x)=N and hashcode(y)=N => x is equal to y

I am not sure how java works internally but I assume this is what happened when I said:

mango = "mango";

java created a string "mango" which was pointed(referenced) by the variable mango something like this

mango ----> "mango"

Now in the next line when I said:

mango2 = "mango";

It actually reused the same string "mango" which looks something like this

mango ----> "mango" <---- mango2

Both mango and mango2 pointing to the same reference Now when I said

mango3 = new String("mango")

It actually created a completely new reference(string) for "mango". which looks something like this,

mango -----> "mango" <------ mango2

mango3 ------> "mango"

and that's why when I put out the values for mango == mango2, it put out true. and when I put out the value for mango3 == mango2, it put out false (even when the values were the same).

and when you uncommented the line // mango2 = "mang"; It actually created a string "mang" which turned our graph like this:

mango ---->"mango"
mango2 ----> "mang"
mango3 -----> "mango"

This is why the identityHashCode is not the same for all.

Hope this helps you guys. Actually, I wanted to generate a test case where == fails and equals() pass. Please feel free to comment and let me know If I am wrong.

查看更多
裙下三千臣
4楼-- · 2018-12-30 23:11

== is an operator and equals() is a method.

Operators are generally used for primitive type comparisons and thus == is used for memory address comparison and equals() method is used for comparing objects.

查看更多
泛滥B
5楼-- · 2018-12-30 23:14

== can be used in many object types but you can use Object.equals for any type , especially Strings and Google Map Markers.

查看更多
旧人旧事旧时光
6楼-- · 2018-12-30 23:18

In general, the answer to your question is "yes", but...

  • .equals(...) will only compare what it is written to compare, no more, no less.
  • If a class does not override the equals method, then it defaults to the equals(Object o) method of the closest parent class that has overridden this method.
  • If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality.
  • Always remember to override hashCode if you override equals so as not to "break the contract". As per the API, the result returned from the hashCode() method for two objects must be the same if their equals methods show that they are equivalent. The converse is not necessarily true.
查看更多
忆尘夕之涩
7楼-- · 2018-12-30 23:18
 String w1 ="Sarat";
 String w2 ="Sarat";
 String w3 = new String("Sarat");

 System.out.println(w1.hashCode());   //3254818
 System.out.println(w2.hashCode());   //3254818
 System.out.println(w3.hashCode());   //3254818

 System.out.println(System.identityHashCode(w1)); //prints 705927765
 System.out.println(System.identityHashCode(w2)); //prints 705927765
 System.out.println(System.identityHashCode(w3)); //prints 366712642


 if(w1==w2)   //  (705927765==705927765)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true

 if(w2==w3)   //  (705927765==366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints false


 if(w2.equals(w3))   //  (Content of 705927765== Content of 366712642)
 {
   System.out.println("true");
 }
 else
 {
   System.out.println("false");
 }
 //prints true
查看更多
登录 后发表回答