Search code examples
javahashhashtablebucket

Memory Address as Hash in HashTable. Why can't HasTable use actual memory address of the Key as Hash?


May be this is a basic question or a basic idea behind this.

Why can't HasTable use actual memory address of the Key as Hash? Or Hash the address of the key and use it?

I saw some posts saying the default hashCode() of the key (object) is actually the Memory address of the object, which I think is not correct.

And I read in a post that says, the bucket address is actually hash % number of existing buckets? This is not correct either.

Can someone clarify?


Solution

  • If a class does not override hashCode(), and just inherits the default implementation from java.lang.Object, then in a typical JVM, its hashCode(), really will be, more or less, an internal pointer to it. (Obviously that's not the whole story, because the return-type of hashCode() is int, which wouldn't accommodate 64-bit JVMs; and these aren't real pointers to physical memory locations, firstly because the OS handles the mapping from virtual addresses to physical ones, and secondly because, even if the JVM handled that, garbage-collectors can move an object from one heap to another without affecting its hashCode(). But still, "internal memory address" is a good first approximation.)

    The reason that most JDK classes override hashCode() is that we always want hashCode() to be "compatible" with equals(); that is, if a.equals(b), then we want a.hashCode() == b.hashCode(). (This makes sense when you consider that you generally don't want — for example — a Map<String, Object> to have two different "abc" entries just because the keys are two different String instances. And generally you'd want to be able to look up an entry by typing map.get("abc"), rather than needing to have the original instance of the key handy. If two keys are equal, then we usually want them to be treated as equal.)

    If you really want pointer-equality in your map, you can use the java.util.IdentityHashMap class.