{"id":166,"date":"2015-01-27T07:05:48","date_gmt":"2015-01-27T07:05:48","guid":{"rendered":"http:\/\/jeffcardillo.com\/blog\/?p=166"},"modified":"2025-04-21T05:11:01","modified_gmt":"2025-04-21T05:11:01","slug":"when-hashcodes-collide-hashcode-and-equals","status":"publish","type":"post","link":"http:\/\/jeffcardillo.com\/blog\/2015\/01\/27\/when-hashcodes-collide-hashcode-and-equals\/","title":{"rendered":"When hashCodes Collide: Overriding hashCode() and equals()"},"content":{"rendered":"<p>We&#8217;ve seen these guys around before (the hashCode and equals methods). We know they are important. In fact, we&#8217;ve heard that there is some soft of &#8220;contract&#8221; we&#8217;re supposed to uphold if we override them. So what does it all mean? Let&#8217;s take a quick look&#8230;<\/p>\n<p><!--more--><\/p>\n<p>The hashCode() and equals()\u00a0methods are part of\u00a0the java.lang.Object class. This\u00a0means that any class that extends java.lang.Object implements the hashCode() and equals() methods.<\/p>\n<p>The equals(Object o) simply allows us to tests for equality between two objects. We can override the equals() method on our objects but there are some rules that we should keep in mind if we do so. These rules are to remind us what it means for two objects to be equal, and we should preserve the\u00a0meaning when modifying the default behavior of the equals method.<\/p>\n<ul>\n<li>REFLEXIVE: x.equals(x) should always return true &#8211; <em>this states that an object\u00a0should always equal itself<\/em><\/li>\n<li>SYMMETRIC: if x.equals(y) = true, then y.equals(x) = true &#8211; <em>this states that if object1 is equal to object2, then we must also be able to say object2 is equal to object1<\/em><\/li>\n<li>TRANSITIVE: if x.equals(y) = true and y.equals(z) = true, then x.equals(z) = true<\/li>\n<li>CONSISTENT: Multiple invocations of x.equals(y) should always consistently return the same result, for a given object x and y.<\/li>\n<\/ul>\n<p>The <strong>hashCode()<\/strong>\u00a0method of Object is used anytime we insert the\u00a0object into a HashMap, HashTable, or HashSet. The hashCode() method effectively generates an index to map objects to.<\/p>\n<p>To <span style=\"text-decoration: underline;\">over simplify<\/span>, think of a hashtable&#8217;s\u00a0main data structure as an array; then if we call hashTable.put(<em>key<\/em>, \u00a0<em>value<\/em>) the HashTable\u00a0will call <em>key<\/em>.hashCode() to figure out the index to store the object <em>key<\/em> in the array.<\/p>\n<p>Just like the contract\u00a0for equals() that keep us honest, we have a contract\u00a0for hashCode() as well. But let&#8217;s pay careful attention to the wording here because it will help us understand what is really going on. I have truncated a couple of the rules so that we can focus on the meat of it. The truncated rules end with an ellipsis (&#8230;), the full rules are available <a href=\"http:\/\/docs.oracle.com\/javase\/6\/docs\/api\/java\/lang\/Object.html#hashCode()\">here<\/a>:<\/p>\n<ol>\n<li>Whenever it is invoked on the same object more than once during an execution of a Java application, the <tt>hashCode<\/tt> method must consistently return the same integer&#8230; &#8211;\u00a0<strong><em>Similar to equals(), this states that our hashCode() function should be consistent and always return the same result if the object has not changed.<\/em><\/strong><\/li>\n<li>If two objects are equal according to the <tt>equals(Object)<\/tt> method, then calling the\u00a0hashCode\u00a0method on each of the two objects must produce the same integer result. &#8211;\u00a0<strong><em>This\u00a0intuitively\u00a0makes sense if you think about how the hashCode() maps objects to\u00a0where they belong in the array. If object are equal they should be stored together.<\/em><\/strong><\/li>\n<li>It is <em>not<\/em> required that if two objects are unequal according to the equals()\u00a0method, then calling the <tt>hashCode<\/tt> method on each of the two objects must produce distinct integer results&#8230; &#8211;\u00a0<strong><em>This is where it gets interesting and I&#8217;ll dig in to it below. <\/em><\/strong>&#8220;&#8230;However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.&#8221;<\/li>\n<\/ol>\n<p>If we look again at\u00a0the somewhat awkwardly worded #3, we see that it says &#8220;it is acceptable that two completely different objects produce the same hashcode&#8221;. This situation is called a hash collision and is completely legal. How is this possible? How do we find objects in the hashtable if different objects can map to the same location? To illustrate how this works, let&#8217;s extend the conceptual model of the hashtable we started above.<\/p>\n<p>I previously over simplified a \u00a0hashtable&#8217;s main data structure as an array. Let&#8217;s continue with this simplification and say that each index of the array stores a Linked List of objects. This means that if we have 3 objects that map to index\u00a05 of the hashtable&#8217;s array, then index 5 of the array will have a Linked List with 3\u00a0nodes; one for each object mapped to that location.<\/p>\n<p>We now have a hashtable construct in our minds that looks like the following- Notice that we have a hashcode collision and the Cat object mapped to the same location as the Dog objects:<\/p>\n<p><a href=\"http:\/\/jeffcardillo.com\/blog\/wp-content\/uploads\/2015\/01\/hash_function21.png\"><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-186 aligncenter\" src=\"http:\/\/jeffcardillo.com\/blog\/wp-content\/uploads\/2015\/01\/hash_function21.png\" alt=\"hash_function2\" width=\"800\" height=\"600\" srcset=\"http:\/\/jeffcardillo.com\/blog\/wp-content\/uploads\/2015\/01\/hash_function21.png 800w, http:\/\/jeffcardillo.com\/blog\/wp-content\/uploads\/2015\/01\/hash_function21-300x225.png 300w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><\/a><\/p>\n<p>We see that the hash function might\u00a0map different objects to the same location in a hashtable and store the objects as a Linked List. So how do we find the object again from the hashtable?\u00a0Simply by traversing the linked list returned from the index at hashCode() and performing equals() on each node until we find the one we are looking for.<\/p>\n<p>Now we see how the hashCode() function and the equals() function are tied together; when we call hashtable.get(object), the hashCode() maps us to where we will find a collection of objects, and then\u00a0each one is checked with equals()\u00a0until we find the the object we are looking for.<\/p>\n<p>If we think about it, if hashcode always returned 1, for example, we would still be able to store and retrieve all of our objects; they would just be in one large list. So why do we need hashCode anyway? The short answer is performance.<\/p>\n<p>Let&#8217;s take a very quick look at <strong>Big-O notation<\/strong> to show the significance of the hashCode() function. Let&#8217;s assume that our hashCode() function does a very good job at distributing different objects among the array structure so that the Linked List structures are very small. This hashtable will have an effective search time of\u00a0O(1). For contrast, let&#8217;s assume the worst case scenario where the hashcode maps every single object to a single location in the array so that we are left with 1 long Linked List\u00a0with all of our objects. The Big-O notation for searching a Linked List is O(n).<\/p>\n<p>We can clearly see from\u00a0Big-O analysis that we want our hashCode function to map different objects to different locations in the array structure so that\u00a0we want to maximize performance. The third contract item from hashCode() above makes a lot of sense.<\/p>\n<h6>What we covered<\/h6>\n<p>We covered what the equals() and hashCode() functions do on Objects. We also covered how they are tied together in the use of a hashtable data structure, and why it is important (but not required) for hashcode() to generate different codes for different objects. I hope this information was useful!<\/p>\n<h6>References<\/h6>\n<p>java.lang.Object:\u00a0<a href=\"http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Object.html\">http:\/\/docs.oracle.com\/javase\/7\/docs\/api\/java\/lang\/Object.html<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>We&#8217;ve seen these guys around before (the hashCode and equals methods). We know they are important. In fact, we&#8217;ve heard that there is some soft of &#8220;contract&#8221; we&#8217;re supposed to uphold if we override them. So what does it all mean? Let&#8217;s take a quick look&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[9,40,10,11,2],"tags":[18,6,20,19],"class_list":["post-166","post","type-post","status-publish","format-standard","hentry","category-android","category-computer-science","category-ios","category-java","category-programming","tag-hashing","tag-hashmap","tag-hashset","tag-hashtable"],"_links":{"self":[{"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/posts\/166","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/comments?post=166"}],"version-history":[{"count":19,"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/posts\/166\/revisions"}],"predecessor-version":[{"id":332,"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/posts\/166\/revisions\/332"}],"wp:attachment":[{"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/media?parent=166"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/categories?post=166"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/jeffcardillo.com\/blog\/wp-json\/wp\/v2\/tags?post=166"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}