Packagecn.xf.cp.ch02.item9;ImportJava.util.HashMap;ImportJava.util.Map; Public classphonenumber{Private Final ShortAreaCode; Private Final Shortprefix; Private Final Shortlinenumber; PublicPhoneNumber (intAreaCode,intPrefixintlinenumber) {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 voidRangecheck (intArgintMax, String name) { if(Arg < 0 | | arg >max)Throw NewIllegalArgumentException (name + ":" +Arg); } @Override Public Booleanequals (Object o) {if(O = = This) return true; if(! (OinstanceofPhoneNumber)) return false; PhoneNumber PN=(PhoneNumber) o; returnPn.linenumber = = LineNumber && Pn.prefix = = Prefix && Pn.areacode = =AreaCode; } /*@Override//As to why use 31, this is the recommended value, the study shows that this number is better than the public int hashcode () {int result = 17; result = * result + AreaCode; result = * result + prefix; result = * result + linenumber; return result; } */ //if an object is not constantly changing, and the cost is relatively large, you have to consider it. Hash code is cached inside the object//with volatile modifiers, the thread will read the variable's most-modified value each time it uses the variable. Private volatile inthashcode; @Override Public inthashcode () {intresult =hashcode; if(Result = = 0) {result= 17; Result= * result +AreaCode; Result= * result +prefix; Result= * result +linenumber; Hashcode=result; } returnresult; } Public Static voidMain (string[] args) {Map<phonenumber, string> m =NewHashmap<phonenumber, string>(); M.put (NewPhoneNumber (707, 867, 5309), "Jenny"); //It's not going to go back to Jenny. Oh, it will return NULL, this is because put object they put in a different hash bucketSystem.out.println (M.get (NewPhoneNumber (707, 867, 5309))); }}
"Effective Java" 5, overwrite equals when always overwrite Hashcode