object - Why is there a need to override hashcode if I override the 'equals' method in Java? -


i know there need override hashcode whenever equals method overridden in java. merely contract. trying understand logic behind this. reading *effective java joshua bloch, , came across code (item 9, page 45):

import java.util.hashmap; import java.util.map;  public final class phonenumber {     private final short areacode;     private final short prefix;     private final short linenumber;      public phonenumber(int areacode, int prefix, int linenumber) {         rangecheck(areacode, 999, "area code");         rangecheck(prefix, 999, "prefix");         rangecheck(linenumber, 9999, "line number");         this.areacode = (short) areacode;         this.prefix = (short) prefix;         this.linenumber = (short) linenumber;     }      private static void rangecheck(int arg, int max, string name) {         if (arg < 0 || arg > max)             throw new illegalargumentexception(name + ": " + arg);     }      @override     public boolean equals(object o) {         if (o == this)             return true;         if (!(o instanceof phonenumber))             return false;         phonenumber pn = (phonenumber) o;         return pn.linenumber == linenumber && pn.prefix == prefix                 && pn.areacode == areacode;     }      // broken - no hashcode method!      // decent hashcode method - page 48     // @override public int hashcode() {     // int result = 17;     // result = 31 * result + areacode;     // result = 31 * result + prefix;     // result = 31 * result + linenumber;     // return result;     // }      // lazily initialized, cached hashcode - page 49     // private volatile int hashcode; // (see item 71)     //     // @override public int hashcode() {     // int result = hashcode;     // if (result == 0) {     // result = 17;     // result = 31 * result + areacode;     // result = 31 * result + prefix;     // result = 31 * result + linenumber;     // hashcode = result;     // }     // return result;     // }      public static void main(string[] args) {         map<phonenumber, string> m = new hashmap<phonenumber, string>();         m.put(new phonenumber(707, 867, 5309), "jenny");         system.out.println(m.get(new phonenumber(707, 867, 5309)));     } } 

this mentions in text, having difficulty understanding.

at point, might expect m.get(new phonenumber(707, 867, 5309)) return "jenny", return null. notice 2 phonenumber instances involved: 1 used insertion hashmap , second, equal, instance used (attempted) retrieval. phonenumber class's failure override hashcode causes 2 equal instances have unequal hashcodes, in violation of hashcode contract. therefore method phone number in different hash bucket 1 in stored put method

i don't understand 2 phonenumber instances talks about. there instance create in m.put(new phonenumber(707, 867, 5309), "jenny"). object again, should return same hashcode if inherits hashcode method object class. why happen? explanation here lot.

i don't understand 2 phonenumber instance talks about.

the first 1 one used insertion.

m.put(new phonenumber(707, 867, 5309), "jenny")); 

the second instance 1 used retrieval.

m.get(new phonenumber(707, 867, 5309)); // notice use of "new" 

also object again, should return same hashcode if inherits hashcode method object class.

that's incorrect. default implementation of hashcode() in object class returns distinct integers distinct objects because implemented converting internal address of object integer. hence, hash code check fails there.

if on other hand, had tried retrieve phonenumber using same instance

phonenumber phonenum = new phonenumber(707, 867, 5309); m.put(phonenum, "jenny")); m.get(phonenum); // not null 

the hash code check pass (since, you've used same object inserted before) , equals() well. of course isn't recommended approach because we're far more use different key object 1 used insertion.

the key used would, however, meaningfully equivalent (like different string object text same) , hence providing hashcode() implementation required match , retrieval happen correctly.

also see: checking , removing elements in java hashmap


Comments

Popular posts from this blog

java - Run a .jar on Heroku -

java - Jtable duplicate Rows -

validation - How to pass paramaters like unix into windows batch file -