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?

jiaweizhang
  • 809
  • 1
  • 11
  • 28
GuruKulki
  • 25,776
  • 50
  • 140
  • 201

8 Answers8

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

Thomas Lötzer
  • 24,832
  • 16
  • 69
  • 55
  • +1 your answer is more likely. – Petrus Theron May 05 '10 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. – David Neale May 05 '10 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 05 '10 at 13:08
  • Agreed - which is why one has to manually override standard equality behaviour to achieve this if necessary. – David Neale May 05 '10 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. – Jean-Philippe Caruana Dec 12 '13 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.

Sean Owen
  • 66,182
  • 23
  • 141
  • 173
  • 2
    Unless you're comparing value types... – David Neale May 05 '10 at 11:44
  • 4
    @David: there's no such thing as "value types" in Java, unless you are talking about primitive values. – Joachim Sauer May 05 '10 at 11:46
  • Sorry - I did mean primitives and good point about not being able to create value types in Java. – David Neale May 05 '10 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 05 '10 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. –  May 25 '10 at 22:04
  • @Tom. Fair enough. I didn't initially notice the Java tag when I read this question so I defaulted to C#. – David Neale May 26 '10 at 09:31
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.

Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • 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 05 '10 at 15:17
  • Nitpicking here, but *two* values are, by definition, never the same (otherwise, it would only be one value). – fredoverflow May 05 '10 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)

drstupid
  • 423
  • 5
  • 8
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;
    }
    }
Mudassir Hasan
  • 28,083
  • 20
  • 99
  • 133
frictionlesspulley
  • 11,070
  • 14
  • 66
  • 115
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.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
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;
    }


}
Ankit Zalani
  • 3,068
  • 5
  • 27
  • 47
-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
    }
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419