srk
srk

Reputation: 5146

How the equals() method works

I am digging into the basics of Java. I infer from this article, that the Java 'equals' method means, if two objects are equal then they must have the same hashCode().

Here's my example.

public class Equals {

    /**
     * @param args
     */
    public static void main(String[] args) {
        String a = new String("a");
        String b = new String("a");
        System.out.println("a.hashCode() "+a.hashCode());
        System.out.println("b.hashCode() "+b.hashCode());
        System.out.println(a == b);
        System.out.println(a.equals(b));
    }

}

Output:

a.hashCode() 97
b.hashCode() 97
false
true

The actual Java language 'equals' method:

  public boolean equals(Object obj) {
    return (this == obj);
  }

In my above example, a.equals(b) has returned true, meaning the condition 'a==b' is satisfied. But then why is 'a==b' returning false in that example?

Aren't hashCode and address one and same? Also, is 'hashCode' compared when we say 'a==b' or something else?

Upvotes: 11

Views: 31438

Answers (8)

AllTooSir
AllTooSir

Reputation: 49432

The String class has overridden the equals() method. Please follow the String equals() documentation.

a.equals(b) has returned true, meaning the condition a==b is satisfied

This is the default implementation of equals() in the Object class, and the String class has overridden the default implementation. It returns true if and only if the argument is not null and is a String object that represents the same sequence of characters as this object.

Aren't hashCode and address one and same?

Not necessarily. For further reading on hashCode().

Upvotes: 14

Gru
Gru

Reputation: 85

public class TestEquals {
    /**
     * @param args
     */
    public static void main(String[] args) {
        String a = new String("a"); 
        String b = new String("a");
        System.out.println("a.hashCode() " + a.hashCode());
        System.out.println("b.hashCode() " + b.hashCode());

        // Checks the reference which is something like the 
        // address & address is different from hash code which can be overriden
        System.out.println(a == b);

        // It returns true if and only if the argument is not null 
        // and is a String object that represents the same sequence 
        // of characters as this object. (String Implementation of equals)
        System.out.println(a.equals(b));
    }
}

Output:

a.hashCode() 97
b.hashCode() 97
false
true

Upvotes: 0

prashant
prashant

Reputation: 1815

Hashcode for an object is meant to be overridden.

For String class the formula used is as follows:

s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

I encourage you to search why 31 has been used as a multiplier and not some other number.

A general thumb rule for overriding hash code is that for different objects hash code should be different as far as possible.

To achieve this it is advisable that you take into account every significant field of an object while calculating the hash value.

Note: Just an unrelated food for thought (source : Effective Java): Consider the following implementation of hashcode

int hashcode(){
     return 10;
}

This is a valid implementation but it is also the worst possible one. Read about why.

Upvotes: 1

dcow
dcow

Reputation: 7985

A and B are two separate objects that generate the same hash code because of String's implementation of hashCode(). == just checks to see if the left and right sides share the same reference. It does not call an Object's equals() method.

So, no, hashes and object references are not the same thing.

Upvotes: 0

rgettman
rgettman

Reputation: 178333

The == operator in Java compares object references to see if they refer to the same object. Because your variables a and b refer to different objects, they are not equal according to ==.

And the hashCode method doesn't return the address in String, because that class has overridden hashCode.

Additionally, the equals method has been implemented in String to compare the contents of the strings; that's why a.equals(b) returns true here.

Upvotes: 4

Ankur Shanbhag
Ankur Shanbhag

Reputation: 7804

String class overrides the default implementation of the equals() method of the Object class. The equals method code that you have provided is not from String class but from the Object class, which is overridden be the String class implementation which checks if the contents of the two objects are same or not.

Upvotes: 1

IndoKnight
IndoKnight

Reputation: 1864

a.equals(b) is different from a==b.

a.equals(b) checks if two objects are equals based on equals() implementation.

a==b checks if two objects have same reference.

If a==b is true then a.equals(b) must be true because they are referencing to the same object but not vice-versa.

Upvotes: 1

CPerkins
CPerkins

Reputation: 9018

No, Hashcode and address aren't the same.

Because a==b is not comparing hashcodes.

Yes, something else is compared when we say a==b.

(that's not addresses either, really, but it's close enough).

Also, just because "equal objects have equal hashcodes" does not mean "equal hashcodes means equal objects".

Upvotes: 3

Related Questions