First I wish to state that I'm aware of the javadoc of java.lang.Object.hashCode() and thus there's no need to mention it again.
What I'm asking is: Why isn't java.lang.Object.hashCode() moved into a seperate interface named (probably) Hashable? Like `java.lang.Comparator'?
To me, hashCode() is only used in hash-dependent data structures like HashMap or HashTable, which a) are not used in every application b) are often used with very few types of keys like String or Integer and not with a InputStream (or something like it).
I know that I do not have to implement hashCode() for every class of mine, however, isn't adding a method to a class at the cost of performance to some extent? Especially for java.lang.Object - the superclass of every class in Java.
Even if special optimization is done within the JVM so that the lost of performance can be ignored, I still think that it's unwise to provide every Object with a behavior that is not frequently implemented at all. According to the Interface Segregation Principle:
No client should be forced to depend on methods it does not use.
I did some searches in the web and the only related page I could find is this.
The first answer expressed (partly) the same idea as mine, and some others tried to answer the question, saying mainly that "hashCode() for every Object enables storage of object of any type in HashMap", which I take as not satisfactory.
I here propose my own solution, which satisfies both the Interface Segregation Principle and the ability to store anything in a HashMap without adding much complexity the whole system:
- Remove
hashCode()fromjava.lang.Object. - Let there be an interface
Hashable, containinghashCode()with the same contract as the formerjava.lang.Object.hashCode(). - Let there be an interface
HashProviderwith a type parameterTcontainingprovideHashCode(T t)to provide a hash code for an object. (Think ofComparator<T>). - Let there be an implementation of
HashProvider<Object>calledDefaultHashProviderwhich generates the hash code for anyObjectusing the current implementation ofObject.hashCode(). (As for Java 8, Object.hashCode() is a native method, I expectDefaultHashProvider.provideHashCode()to return the same thing for anyObject) - Modify constructors of
HashMapandHashTableso that everything can be stored in them by:- Using the
provideHashCode()if aHashProvideris specified. - Using the
hashCode()if its underlying elements implementHashable. - Using
DefaultHashProviderotherwise.
- Using the
I believe that this is possible in practice because it's just a variation of the system of Comparable, Comparator and TreeMap.
And let my repeat my question:
Considering that the Java development team should not be unable to come up with a solution similar to mine, is there any good reason for not doing so? Are there some advanced considerations that I'm currently unaware of? I have the following hypotheses, does any of them approach the correct answer?
- Some language features required by this solution, like generic types, are available only well after the very beginning of Java - since 1.5. However, I would argue that
Comparator,Comparablealong withTreeMapexist since 1.2, can't the technique used to write them be adapted toHashMap? hashCode()is used somewhere within the JVM and therefore it requires everyObjectto have a hash code. However this can also be available usingDefaultHashProvider.provideHashCode()(or its native implementation) for non-hashables.