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

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

This question is related to java identity equality object-comparison

The answer is


The String pool (aka interning) and Integer pool blur the difference further, and may allow you to use == for objects in some cases instead of .equals

This can give you greater performance (?), at the cost of greater complexity.

E.g.:

assert "ab" == "a" + "b";

Integer i = 1;
Integer j = i;
assert i == j;

Complexity tradeoff: the following may surprise you:

assert new String("a") != new String("a");

Integer i = 128;
Integer j = 128;
assert i != j;

I advise you to stay away from such micro-optimization, and always use .equals for objects, and == for primitives:

assert (new String("a")).equals(new String("a"));

Integer i = 128;
Integer j = 128;
assert i.equals(j);

You will have to override the equals function (along with others) to use this with custom classes.

The equals method compares the objects.

The == binary operator compares memory addresses.


When you evaluate the code, it is very clear that (==) compares according to memory address, while equals(Object o) compares hashCode() of the instances. That's why it is said do not break the contract between equals() and hashCode() if you do not face surprises later.

    String s1 = new String("Ali");
    String s2 = new String("Veli");
    String s3 = new String("Ali");

    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());
    System.out.println(s3.hashCode());


    System.out.println("(s1==s2):" + (s1 == s2));
    System.out.println("(s1==s3):" + (s1 == s3));


    System.out.println("s1.equals(s2):" + (s1.equals(s2)));
    System.out.println("s1.equal(s3):" + (s1.equals(s3)));


    /*Output 
    96670     
    3615852
    96670
    (s1==s2):false
    (s1==s3):false
    s1.equals(s2):false
    s1.equal(s3):true
    */

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


 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

Here is a general thumb of rule for the difference between relational operator == and the method .equals().

object1 == object2 compares if the objects referenced by object1 and object2 refer to the same memory location in Heap.

object1.equals(object2) compares the values of object1 and object2 regardless of where they are located in memory.

This can be demonstrated well using String

Scenario 1

 public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = new String("Hello");
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

 }



The result is
      is str1 == str2 ? false
      is str1.equals(str2) ? true 

Scenario 2

public class Conditionals {

    public static void main(String[] args) {
       String str1 = "Hello";
       String str2 = "Hello";
       System.out.println("is str1 == str2 ? " + (str1 == str2 ));
       System.out.println("is str1.equals(str2) ? " + (str1.equals(str2 )));
    }

}

The result is 
  is str1 == str2 ? true
  is str1.equals(str2) ? true

This string comparison could be used as a basis for comparing other types of object.

For instance if I have a Person class, I need to define the criteria base on which I will compare two persons. Let's say this person class has instance variables of height and weight.

So creating person objects person1 and person2 and for comparing these two using the .equals() I need to override the equals method of the person class to define based on which instance variables(heigh or weight) the comparison will be.

However, the == operator will still return results based on the memory location of the two objects(person1 and person2).

For ease of generalizing this person object comparison, I have created the following test class. Experimenting on these concepts will reveal tons of facts.

package com.tadtab.CS5044;

public class Person {

private double height;
private double weight;

public double getHeight() {
    return height;
}

public void setHeight(double height) {
    this.height = height;
}

public double getWeight() {
    return weight;
}

public void setWeight(double weight) {
    this.weight = weight;
}


@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(height);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}

@Override
/**
 * This method uses the height as a means of comparing person objects.
 * NOTE: weight is not part of the comparison criteria
 */
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Person other = (Person) obj;
    if (Double.doubleToLongBits(height) != Double.doubleToLongBits(other.height))
        return false;
    return true;
}

public static void main(String[] args) {
    
    Person person1 = new Person();
    person1.setHeight(5.50);
    person1.setWeight(140.00);
    
    Person person2 = new Person();
    person2.setHeight(5.70);
    person2.setWeight(160.00);
    
    Person person3 = new Person();
    person3 = person2;
    
    Person person4 = new Person();
    person4.setHeight(5.70);
    
    Person person5 = new Person();
    person5.setWeight(160.00);
    
    System.out.println("is person1 == person2 ? " + (person1 == person2)); // false;
    System.out.println("is person2 == person3 ? " + (person2 == person3)); // true 
    //this is because perosn3 and person to refer to the one person object in memory. They are aliases;
    System.out.println("is person2.equals(person3) ? " + (person2.equals(person3))); // true;
    
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person4))); // true;
    
    // even if the person2 and person5 have the same weight, they are not equal.
    // it is because their height is different
    System.out.println("is person2.equals(person4) ? " + (person2.equals(person5))); // false;
}

}

Result of this class execution is:

is person1 == person2 ? false
is person2 == person3 ? true
is person2.equals(person3) ? true
is person2.equals(person4) ? true
is person2.equals(person4) ? false

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 major difference between == and equals() is

1) == is used to compare primitives.

For example :

        String string1 = "Ravi";
        String string2 = "Ravi";
        String string3 = new String("Ravi");
        String string4 = new String("Prakash");

        System.out.println(string1 == string2); // true because same reference in string pool
        System.out.println(string1 == string3); // false

2) equals() is used to compare objects. For example :

        System.out.println(string1.equals(string2)); // true equals() comparison of values in the objects
        System.out.println(string1.equals(string3)); // true
        System.out.println(string1.equals(string4)); // false

Also note that .equals() normally contains == for testing as this is the first thing you would wish to test for if you wanted to test if two objects are equal.

And == actually does look at values for primitive types, for objects it checks the reference.


public class StringPool {

public static void main(String[] args) {

    String s1 = "Cat";// will create reference in string pool of heap memory
    String s2 = "Cat";
    String s3 = new String("Cat");//will create a object in heap memory

    // Using == will give us true because same reference in string pool

    if (s1 == s2) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using == with reference and Object will give us False

    if (s1 == s3) {
        System.out.println("true");
    } else {
        System.out.println("false");
    }

    // Using .equals method which refers to value

    if (s1.equals(s3)) {
        System.out.println("true");
    } else {
        System.out.println("False");
    }

    }
  }

----Output----- true false true


It is the difference between identity and equivalence.

a == b means that a and b are identical, that is, they are symbols for very same object in memory.

a.equals( b ) means that they are equivalent, that they are symbols for objects that in some sense have the same value -- although those objects may occupy different places in memory.

Note that with equivalence, the question of how to evaluate and compare objects comes into play -- complex objects may be regarded as equivalent for practical purposes even though some of their contents differ. With identity, there is no such question.


Since Java doesn’t support operator overloading, == behaves identical for every object but equals() is method, which can be overridden in Java and logic to compare objects can be changed based upon business rules.

Main difference between == and equals in Java is that "==" is used to compare primitives while equals() method is recommended to check equality of objects.

String comparison is a common scenario of using both == and equals() method. Since java.lang.String class override equals method, It return true if two String object contains same content but == will only return true if two references are pointing to same object.

Here is an example of comparing two Strings in Java for equality using == and equals() method which will clear some doubts:

 public class TEstT{

        public static void main(String[] args) {
            
    String text1 = new String("apple");
    String text2 = new String("apple");
          
    //since two strings are different object result should be false
    boolean result = text1 == text2;
    System.out.println("Comparing two strings with == operator: " + result);
          
    //since strings contains same content , equals() should return true
    result = text1.equals(text2);
    System.out.println("Comparing two Strings with same content using equals method: " + result);
          
    text2 = text1;
    //since both text2 and text1d reference variable are pointing to same object
    //"==" should return true
    result = (text1 == text2);
    System.out.println("Comparing two reference pointing to same String with == operator: " + result);

    }
    }

== 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.


Basically, == compares if two objects have the same reference on the heap, so unless two references are linked to the same object, this comparison will be false.

equals() is a method inherited from Object class. This method by default compares if two objects have the same referece. It means:

object1.equals(object2) <=> object1 == object2

However, if you want to establish equality between two objects of the same class you should override this method. It is also very important to override the method hashCode() if you have overriden equals().

Implement hashCode() when establishing equality is part of the Java Object Contract. If you are working with collections, and you haven't implemented hashCode(), Strange Bad Things could happen:

HashMap<Cat, String> cats = new HashMap<>();
Cat cat = new Cat("molly");
cats.put(cat, "This is a cool cat");
System.out.println(cats.get(new Cat("molly"));

null will be printed after executing the previous code if you haven't implemented hashCode().


The == operator tests whether two variables have the same references (aka pointer to a memory address).

String foo = new String("abc");
String bar = new String("abc");

if(foo==bar)
// False (The objects are not the same)

bar = foo;

if(foo==bar)
// True (Now the objects are the same)

Whereas the equals() method tests whether two variables refer to objects that have the same state (values).

String foo = new String("abc");
String bar = new String("abc");

if(foo.equals(bar))
// True (The objects are identical but not same)

Cheers :-)


== operator always reference is compared. But in case of

equals() method

it's depends's on implementation if we are overridden equals method than it compares object on basic of implementation given in overridden method.

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//fasle
      obj==obj1 // fasle
    }
 }

in above code both obj and obj1 object contains same data but reference is not same so equals return false and == also. but if we overridden equals method than

 class A
 {
   int id;
   String str;

     public A(int id,String str)
     {
       this.id=id;
       this.str=str;
     }
    public boolean equals(Object obj)
    {
       A a1=(A)obj;
      return this.id==a1.id;
    }

    public static void main(String arg[])
    {
      A obj=new A(101,"sam");
      A obj1=new A(101,"sam");

      obj.equals(obj1)//true
      obj==obj1 // fasle
    }
 }

know check out it will return true and false for same case only we overridden

equals method .

it compare object on basic of content(id) of object

but ==

still compare references of object.


It may be worth adding that for wrapper objects for primitive types - i.e. Int, Long, Double - == will return true if the two values are equal.

Long a = 10L;
Long b = 10L;

if (a == b) {
    System.out.println("Wrapped primitives behave like values");
}

To contrast, putting the above two Longs into two separate ArrayLists, equals sees them as the same, but == doesn't.

ArrayList<Long> c = new ArrayList<>();
ArrayList<Long> d = new ArrayList<>();

c.add(a);
d.add(b);
if (c == d) System.out.println("No way!");
if (c.equals(d)) System.out.println("Yes, this is true.");

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.


In short, the answer is "Yes".

In Java, the == operator compares the two objects to see if they point to the same memory location; while the .equals() method actually compares the two objects to see if they have the same object value.


Both == and .equals() refers to the same object if you don't override .equals().

Its your wish what you want to do once you override .equals(). You can compare the invoking object's state with the passed in object's state or you can just call super.equals()


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:


Just remember that .equals(...) has to be implemented by the class you are trying to compare. Otherwise, there isn't much of a point; the version of the method for the Object class does the same thing as the comparison operation: Object#equals.

The only time you really want to use the comparison operator for objects is wen you are comparing Enums. This is because there is only one instance of an Enum value at a time. For instance, given the enum

enum FooEnum {A, B, C}

You will never have more than one instance of A at a time, and the same for B and C. This means that you can actually write a method like so:

public boolean compareFoos(FooEnum x, FooEnum y)
{
    return (x == y);
}

And you will have no problems whatsoever.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to identity

Firebase: how to generate a unique numeric ID for key? ASP.NET MVC 5 - Identity. How to get current ApplicationUser SQL Server 2012 column identity increment jumping from 6 to 1000+ on 7th entry Auto increment primary key in SQL Server Management Studio 2012 What is the difference between == and equals() in Java? SQL Server, How to set auto increment after creating a table without data loss? Where is the Microsoft.IdentityModel dll What is the difference between Scope_Identity(), Identity(), @@Identity, and Ident_Current()? Why does comparing strings using either '==' or 'is' sometimes produce a different result? Handling identity columns in an "Insert Into TABLE Values()" statement?

Examples related to equality

Python if not == vs if != Comparing arrays for equality in C++ Correct way to override Equals() and GetHashCode() Determine if 2 lists have the same elements, regardless of order? equals vs Arrays.equals in Java What is the difference between == and equals() in Java? What's the difference between equal?, eql?, ===, and ==? bash string equality jQuery object equality String comparison in Python: is vs. ==

Examples related to object-comparison

What is the difference between == and equals() in Java? How to compare two object variables in EL expression language? How do I compare two Integers? Object comparison in JavaScript