Path: csiph.com!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!npeer03.iad.highwinds-media.com!news.highwinds-media.com!feed-me.highwinds-media.com!nx01.iad01.newshosting.com!newshosting.com!news-out.readnews.com!transit3.readnews.com!news-out.news.tds.net!newsreading01.news.tds.net!53ab2750!not-for-mail From: "Jan Burse" Subject: Re: hashCode Message-ID: <50269FD2.56654.calajapr@time.synchro.net> X-Comment-To: bob smith Newsgroups: comp.lang.java.programmer In-Reply-To: <50254C53.56590.calajapr@time.synchro.net> References: <50254C53.56590.calajapr@time.synchro.net> X-FTN-AREA: COMP.LANG.JAVA.PROGRAMMER X-FTN-MSGID: 1:261/38 6acfc12e X-FTN-REPLY: 1:261/38 5ddc2510 Content-Type: text/plain; charset=IBM437 Content-Transfer-Encoding: 8bit X-Gateway: time.synchro.net [Synchronet 3.16a-Win32 NewsLink 1.98] Lines: 86 Date: Sat, 11 Aug 2012 18:17:55 GMT NNTP-Posting-Host: 69.21.70.65 X-Complaints-To: news@tds.net X-Trace: newsreading01.news.tds.net 1344709075 69.21.70.65 (Sat, 11 Aug 2012 13:17:55 CDT) NNTP-Posting-Date: Sat, 11 Aug 2012 13:17:55 CDT Organization: tds.net X-Received-Bytes: 4438 Xref: csiph.com comp.lang.java.programmer:17706 To: bob smith From: Jan Burse bob smith schrieb: > Is it always technically correct to override the hashCode function like so: > > @Override > public int hashCode() { > return 1; > } > > Would it be potentially better if that was Object's implementation? > Maybe it would make sense to spell out what the contract for hashCode() is. Well the contract is simply, the following invariant should hold: /* invariant that should hold */ if a.equals(b) then a.hashCode()==b.hashCode() It should be noted that this does not imply: /* not implied and thus not required by the invariant */ if a.hashCode()==b.hashCode() then a.equals(b) It is also quite unlikely that a hashCode() would satisfy the later, although the closer it comes to the later, the better it works for HashMap, etc.. The default objects implementation of hashCode() matches the default objects impementation of equals(). The default objcts implementation of equals() is ==. And the default objects implementation of hashCode() is System.identityHashCode(). The System identity hash code is stored in the object and generated by the system. It does not change during GC although the internal object address might change during GC. It is only 32bit although internal object addresses might by 64bit with a corresponding JVM. Returning a constant, any constant c not only 1, would be technically correct correct for the default implementation of the class object. Since it trivially satisfies the invariant: if a.equals(b) then c==c is trivially true, since c==c is true. But it is not better. Since you would get very degenerated HashMaps, etc.. You need to override the hashhCode() when there is danger that the invariant is not anymore satisified. This is not the case when equals() is not overridden. So overriding hashCode() just for fun when equals() is not overriden, usually doesn't make sense. It will probably only slow down the hashCode() calculation. So the following: hashCode() = sum attr_i * c^i Is not necessary. But it would be a possible way to go when equals() were overriden in the following way: equals(other) = and_i attr_i.equals(other.attr_i) The above happens when you turn your object into a container of other objects irrespective of the own object identity. But beware if the container contains itself somewhere. This is why we find in the code for Hashtable the following complication: public synchronized int hashCode() { /* * This code detects the recursion caused by computing the hash code * of a self-referential hash table and prevents the stack overflow * that would otherwise result. This allows certain 1.1-era * applets with self-referential hash tables to work. This code * abuses the loadFactor field to do double-duty as a hashCode * in progress flag, so as not to worsen the space performance. * A negative load factor indicates that hash code computation is * in progress. */ Interestingly it will return a constant for the object when it detects a loop. Maybe one could do better... Dunno Bye --- BBBS/Li6 v4.10 Dada-1 * Origin: Prism bbs (1:261/38) --- Synchronet 3.16a-Win32 NewsLink 1.98 Time Warp of the Future BBS - telnet://time.synchro.net:24