What is the difference between == and equals() in Java?

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.

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:

  • ==: 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)

With respect to the String class:

The equals() method compares the "value" inside String instances (on the heap) irrespective if the two object references refer to the same String instance or not. If any two object references of type String refer to the same String instance then great! If the two object references refer to two different String instances .. it doesn't make a difference. Its the "value" (that is: the contents of the character array) inside each String instance that is being compared.

On the other hand, the "==" operator compares the value of two object references to see whether they refer to the same String instance. If the value of both object references "refer to" the same String instance then the result of the boolean expression would be "true"..duh. If, on the other hand, the value of both object references "refer to" different String instances (even though both String instances have identical "values", that is, the contents of the character arrays of each String instance are the same) the result of the boolean expression would be "false".

As with any explanation, let it sink in.

I hope this clears things up a bit.


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.