23

I understand why providing same hashcode for two equal (through equals) objects is important. But is the vice versa true as well, if two objects have same hashcode do they have to be equal? Does the contract still hold? I cannot find an example where this could happen, because if all those attributes that are taking part in equals method are being used to override hashcode method as well then we will always same hashcode of objects that are equal. Please comment.

Abidi
  • 7,846
  • 14
  • 43
  • 65
  • 2
    See http://stackoverflow.com/questions/4360035/why-hashcode-can-return-the-same-value-for-different-objects-in-java – esaj Mar 26 '11 at 15:05

10 Answers10

66

If two objects have the same hashcode then they are NOT necessarily equal. Otherwise you will have discovered the perfect hash function.

But the opposite is true: if the objects are equal, then they must have the same hashcode.

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
  • 8
    +1 this is also relevant to hashed objects in general, not only java object. – MByD Mar 26 '11 at 15:08
  • Consider this [example](http://docs.oracle.com/javase/tutorial/java/IandI/objectclass.html) Here `firstBook` and `secondBook` have different hashcodes.So how your statement is true `if the objects are equal then they have the same hashcode` – Fresher May 21 '14 at 13:10
  • @Fresher - Sorry for the late answer. When two objects are equal, you must override hashcode so that the hashcodes are equal too. Otherwise you will have problems when you use the object in a collection. In your given example, they have written `If you override equals(), you must override hashCode() as well.` You see only the `equals` method declared, because they are talking only about the `equals` in the paragraph. Note that there is `...` above it. This means the `hashcode` method was not written on purpose, so they show only the `equals` method. But the `hashcode` method must be added. – Petar Minchev Jun 03 '14 at 06:04
  • So you are saying that `you must override hashcode so that the hashcodes are equal too.`That means you are saying that `firstBook and secondBook` have equal hashcode or you are saying that we must override hashcode method so that we make both their hashcode equals. – Fresher Jun 04 '14 at 06:15
  • @Fresher - I am saying that you must override hashcode method, so the hashcodes are equal, when equals returns true. This means you must use the same fields in hashcode which you use in the equals comparison. – Petar Minchev Jun 04 '14 at 06:45
  • Could you give an example where "If two objects have the same hashcode then they are NOT necessarily equal." I find that hard to comprehend considering "if the objects are equal, then they must have the same hashcode." How can 2 objects not be the same if they have the same hashcode? Because you generate the same hashcode *only* when 2 objects are the same. – NoName Jun 24 '17 at 06:22
  • Well java hashcode is just a function which maps an object to an integer. Depending on the implementation of the hashcode function, two different objects could produce the same hashcode. It is called a collision. You want to minimize the number of collisions, but is not always easy and possible to implement a perfect hash function (a function producing no collisions). Because the hashcode is int and int type has only 2^32 possible values. Let assume you want to compute hashcode of strings. The possible amount of strings is far greater than the 2^32 possible values for the int type. – Petar Minchev Jun 27 '17 at 19:47
  • Read this article and it will become more clear - https://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/ – Petar Minchev Jun 27 '17 at 19:47
  • Read also "Alexandros" answer below for a concrete example. – Petar Minchev Jun 27 '17 at 19:51
10

The purpose of the hashCode function is allow objects to be quickly partitioned into sets of things that are known to unequal to all items outside their own set. Suppose one has 1,000 items and one divides them into ten roughly-equal-sized sets. One call to hashCode could quickly identify the item as being not equal to 900 of the items, without having to use equals on any of those items. Even if one had to use equals to compare the item to 100 other items, that would still be only 1/10 the cost of comparing it to all 1000 items. In practice, even in a large collection, hashCode will often eliminate 99.9% or more of the unequal items, leaving at most a handful to be examined.

supercat
  • 77,689
  • 9
  • 166
  • 211
7

According to the Javadoc in: http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29

It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

Edit: In the real world two Strings may have the same hash code. For instance, if you want to store all string combinations that contain lowercase English letters (like "aaaaaaaaaa","aaaaaaaaab" and so on) of length 10, you can't assign a unique hash code to each of the 141.167.095.653.376 combinations, since int in Java is 32-bit and, therefore, can have up to 4.294.967.296 distinct values.

Alexandros
  • 3,044
  • 1
  • 23
  • 37
5

hashCode value depends on the implementation. for example String class implements hashCode() function depending upon the value. it means

String a=new String("b");
String b=new String("b");

will have same hashcode but, these are two different objects. and a==b will return false.

Danny Beckett
  • 20,529
  • 24
  • 107
  • 134
neonleo
  • 194
  • 1
  • 2
3

Curiously, NumberFormat is an example of a Java foundation class which violates the recommendation that:

As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.

Here is some code showing this, at least under the version of Java I'm currently running under Mac OS X 10.6.

Numberformat nf = NumberFormat.getNumberInstance();
NumberFormat nf2 = NumberFormat.getNumberInstance();
assert nf != nf2;  // passes -- they are different objects
assert !nf.equals(nf2);  // passes -- they are not equal
assert nf.hashCode() != nf2.hashCode();  // fails -- same hash code
owler
  • 1,059
  • 8
  • 13
3

As a matter of fact

public int hashCode(){
    return 1;
}

Is a valid hashcode implementation...but a terrible one. Will make all your hashtables slow. But yes, you can have two different objects with the same hashcode. But that should not be the general case, a real implementation should give different hashcodes for different values most of the time.

Pablo Grisafi
  • 5,039
  • 1
  • 19
  • 29
  • This is a valid argument. The only property a hash code has to satisfy to ensure correctness is that the hash codes should be different *only* if the underlying data structures are different. This is because different hash codes, by design, imply different underlying structures. – Jasim Sep 25 '12 at 07:37
  • What do you mean by "different underlying structures"? – NoName Jun 24 '17 at 06:27
0

Hash code method returns integer. If range of integer finishes then also two different object will have same hash code. So it is not necessary that two different object will have same hash code are equal.

Sushant Kumar Singh
  • 323
  • 1
  • 5
  • 18
0

To prove , if two objects have the same hashCode does not mean that they are equal

Say you have two user defined classes

    class Object1{
        private final int hashCode = 21;
        public int hashCode(){
            return hashCode;
        }

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

    class Object2{
        private final int hashCode = 21;
        public int hashCode(){
            return hashCode;
        }

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

    Object1 object1 = new Object1();
    Object2 object2 = new Object2(); 

    Object1 object3 = new Object1();


    if(object1.hashCode() == object2.hashCode()){
         // return true, because the hashcodes are same
    }

    but 
    if(object1.equals(object3)){
            // will fail, because two different objects   
    }
Mudassar
  • 3,135
  • 17
  • 22
0

hashcode() returns a unique integer ID for each object. If an object’s hashcode is not the same as another object’s hashcode, there is no reason to execute the equals() method: you just know the two objects are not the same. On the other hand, if the hashcode is the same, then you must execute the equals() method to determine whether the values and fields are the same.

Tonnie
  • 4,865
  • 3
  • 34
  • 50
0

Whenever two different objects have the same hash code, we call this a collision. A collision is nothing critical, it just means that there is more than one object in a single bucket, so a HashMap lookup has to look again to find the right object. I found it from here, hope this helps. https://eclipsesource.com/blogs/2012/09/04/the-3-things-you-should-know-about-hashcode/#:~:text=HashCode%20collisions,to%20find%20the%20right%20object.