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
HashProvider
with a type parameterT
containingprovideHashCode(T t)
to provide a hash code for an object. (Think ofComparator<T>
). - Let there be an implementation of
HashProvider<Object>
calledDefaultHashProvider
which generates the hash code for anyObject
using 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
HashMap
andHashTable
so that everything can be stored in them by:- Using the
provideHashCode()
if aHashProvider
is specified. - Using the
hashCode()
if its underlying elements implementHashable
. - Using
DefaultHashProvider
otherwise.
- 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
,Comparable
along withTreeMap
exist 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 everyObject
to have a hash code. However this can also be available usingDefaultHashProvider.provideHashCode()
(or its native implementation) for non-hashables.