35

When i see the implementation of equals() method it does nothing but same as what == does. So my question is what was the need to have this as separate method when we have == operator which does the same work?

0

8 Answers 8

44

You can not overload the == operator, but you can override equals(Object) if you want it to behave differently from the == operator, i.e. not compare references but actually compare the objects (e.g. using all or some of their fields).

Also, if you do override equals(Object), have a look at hashCode() as well. These two methods need to be compatible (i.e. two objects which are equal according to equals(Object) need to have the same hashCode()), otherwise all kinds of strange errors will occur (e.g. when adding the objects to a set or map).

5
  • +1 your answer is more likely. May 5, 2010 at 11:37
  • Correct - if you were to instantiate two separate objects with identical fields and set those fields the same on both objects then testing for equality would still return false. If you were to override Equals() on the class then you could test the fields and return true if they are identical. May 5, 2010 at 11:40
  • 5
    Equality is not the same as identity. Two Ten Dollar notes are equal (within the realms of the model of money) but they are not the same note.
    – ptomli
    May 5, 2010 at 13:08
  • Agreed - which is why one has to manually override standard equality behaviour to achieve this if necessary. May 5, 2010 at 14:20
  • I don't understand why you are talking about overriding. In the context of the queston I find it irrelevant (sorry). As said in other answers, == compares object references and equals() compares object contents. Dec 12, 2013 at 13:34
35

== compares object references, and asks whether the two references are the same.

equals() compares object contents, and asks whether the objects represent the same concept.

6
  • 2
    Unless you're comparing value types... May 5, 2010 at 11:44
  • 4
    @David: there's no such thing as "value types" in Java, unless you are talking about primitive values. May 5, 2010 at 11:46
  • Sorry - I did mean primitives and good point about not being able to create value types in Java. May 5, 2010 at 14:18
  • But primitives don't have an equals() function, just theitr autoboxed type has it. And then the results will also just be equal, if e.g. the number is < 200 or < 100, don't know for now. System.out.println(new Integer(55).equals(new Integer(55))); System.out.println(new Integer(5555).equals(new Integer(555))); prints true false
    – Daniel
    May 5, 2010 at 15:49
  • @david: i think it goes without saying that primitives don't have methods and therefore any sensible person should make this distinction.
    – user132014
    May 25, 2010 at 22:04
19

In case of primitives, the == operator checks if two values are the same.
If it aren't primitives, it checks if it are two pointers (or references) pointing to the same instance of an object.

The equals() method performs a custom check, which is in Object checking the reference, by using ==. But in other classes, sometimes equals() is overridden (I don't know if this is a correct past participle). equals() have to check the content.

So, for example:

int i0 = 34;
int i1 = 34;
int i2 = 35;
// results
i0 == i1: true
i1 == i0: true
i2 == i0: false

But if we have non-primitives

String str0 = new String("Hello man!");
String str1 = new String("Hello man!");
String str2 = new String("!nam olleH");
String str2copy = str2;
// Results
str0 == str1: false // Pointer to two different object, so == will give false
str1 == str2: false // Idem
str2 == str2copy: true // So this are two pointers to the same object
str0.equals(str1): true // This are not the same objects, but they are equal
str1 == str1: true // Again: two times a pointer to the same  object

So, why str0.equals(str1) returns true? Because the String class has an override of equals(). And in that method it doesn't check if they are equal by doing return this == obj; But in that method, there is a full check. I don't know which method they use to compare the two strings, but here are two possible ways:

  • Generating from the the two string a hash-code and check if they are equal (int == int)
  • Checking character by character if they are the same.

So I hope this is clear now.

2
  • That's a nice summary. Just as a further note when using String literals the behaviour is different again... String str0 = "Hello man!"; String str1 = "Hello man!"; str0 == str1; Would return true as the JVM places literal String objects within the String pool. Hence both str1 and str2 refer to the same object in the pool.
    – mmccomb
    May 5, 2010 at 15:17
  • Nitpicking here, but two values are, by definition, never the same (otherwise, it would only be one value). May 5, 2010 at 23:16
2

There is a very important difference between the two.

"==" compares object instances. The default equals() implementation does this, also. Please run & analyse the following code sample:

public class Person{
   String name;

   public Person(String name){
       this.name = name;
   }

//overriding equals
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( name == null ) {
            if( other.name != null )
            return false;
    } else if( !name.equals( other.name ) )
        return false;
    return true;
    }
     }

    ...
    ...
    Person john1 = new Person("John");
    Person john2 = new Person("John");
    System.out.println("john1 == john2:" + (john1 == john2));
    System.out.println("john1.equals(john2):" + john1.equals(john2));

As you can see, "==" will return false (the objects are two different instances of Person), whereas equals will return true (because we defined that 2 Persons are equal when they have the same name)

2

== operator is used to compare references.
equals() method is defined over object definition.

Dog d =new Dog();
Collar c =new Collar("Red");
 d.setCollar(c);
Dog d2=new Dog();
 Collar c2=new Collar("Red");
d2.setCollar(c2);

 d2.getCollar() ==d.getCollar()

would return false indicating that the the two dogs have two different collar object (items).they do not share the same collar.

d2.getCollar().equals(d.getCollar())

return true if the Collar is defined as [Collar are same if color of Collar are same] the two dogs have same colored collar.

   class Collar{
    String color="";
    public Collar(String p0){
    this.color=p0;
    }
    boolean equals(Object c){
      Collar other=(Collar)c;
      return  this.color.equals(other.getColor());
    }

    public String getColor(){
      return this.color;
    }
    }
1

That's done so to make this possible:

String s1 = new String("foo");
String s2 = new String("foo");

System.out.println(s1 == s2); // false?! Different references!
System.out.println(s1.equals(s2)); // true

If you check the source of String#equals(), you'll see that it has overridden the Object#equals() appropriately to compare each other's internal character array (the actual value). Many other classes have this method overridden as well.

0

In java equals operator(==) operates on data of two variables if the operands are of primitive data types. But if the operands are objects java compares them using references because it has no way to figure out to compare on which field or fields of the object.

So there is only one way to compare based on user defined fields and that is defined in the object by overriding equals() methods, since equals operator(==) cannot be overrided in java as java does not supports operator overriding.

As an example if you want to compare Employee on the basis of name you need to define it's logic by overriding equals method in Employee class as below:

public class Employee {
    private Integer id;
    private String name;

    @Override
    public boolean equals(Object obj) {
        Employee other = (Employee) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }


}
-1

"string" == "string" will return false "string".equals("string") will return true

With o1 == o2 you compare that the object 1 is the same object than o2 (by reference)

With o1.equals(o2), depending on the object the equals method is overriden and not implemented with something like "return o1 == o2"

For exemple you create 2 Set instances These 2 set objects are 2 different objects, you can add different elements in any of those. set1 == set2 will always return false but set1.equals(set2) will eventually return true if the set2 contains exactly the same elements that set1... and because equals method is overriden in the Set class...

Equals implementation for Set is:

      public boolean equals(Object o) {
        if (o == this)
           return true;

        if (!(o instanceof Set))
             return false;
        Set s = (Set) o;
        if (s.size() != c.size())
             return false;
        return containsAll(s); // Invokes safe containsAll() above
    }
3
  • 1
    I suspect you mean string1 == string2 and string1.equals(string2)—both the examples in your answer will return false. May 5, 2010 at 11:49
  • sorry for sure i mean "string" == "string" and "string".equals("string") May 5, 2010 at 11:51
  • 6
    "string" == "string" will actually evaluate to true.
    – jarnbjo
    May 5, 2010 at 11:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.