1

I know that the hashmap keys should be immutable objects or at least have a consistent hashcode to properly retrieve its value from the Map/Set. But if I use a mutating object as key without overriding hashcode or equals, will its hashcode be consistent thought its life cycle. I have tried it to retrive hashcode of a mutating object and have found it consistent always.

Edge
  • 722
  • 2
  • 7
  • 21

4 Answers4

4

The contract for hashcode states:

Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.

So there is no guarantee that the hashcode won't change if you mutate your object. It happens that some JDK implementations might use some sort of internal address but they don't have to so you should not rely on that.

Community
  • 1
  • 1
assylias
  • 321,522
  • 82
  • 660
  • 783
  • In this answer - https://stackoverflow.com/a/11807339/4691279 ... if this is true that memory address from initial allocation is entered into object header and hashCode always returns the same, then isn't it possible that two objects can end up with same hashCode() value? If you could please throw some light on this.. – hagrawal7777 Feb 25 '22 at 20:59
  • Hashcodes are not unique - for example a hashcode method that `return 1;` is valid. You may want to search for "hashcode collision", there are several Q&A on Stackoverflow, e.g. https://stackoverflow.com/q/4360035/829571 – assylias Feb 27 '22 at 13:55
  • Thanks for your reply.. yes, that I know.. my point is that suppose hashCode() method is not overriden.. and an object o1 get allocated at memory location abc123.. so when hashcode() is called on it then abc123 will be returned and this will always be true.. and as per stackoverflow.com/a/11807339/4691279 answer this will always be the case because initial memory address is written in the header.. now, suppose that object o1 gets moved to old generation.. and another new object o2 gets created at abc123.. and here as well since hashcode() is not overriden so we will get abc123.. [continued...] – hagrawal7777 Feb 28 '22 at 14:13
  • so essentially two objects returning same hashCode.. please note that this is possible and also know about hashcode collision.. I know the hyothetical scenario mentioned in my above comment can be true or not.. – hagrawal7777 Feb 28 '22 at 14:14
  • 1
    What you describe is probably true for hotspot. But this is not specified by the JVM specifications. It means that another JVM may use different algorithms: what you are saying may be true on hotspot and false on IBM JVM for example. Feel free to ask a separate question if you want more details. – assylias Mar 03 '22 at 21:06
3

The default hash code of the object will not change over time in the latest version of the HotSpot JVM. In fact, the hash code is derived from the initial allocation address and entered in the object header (see JVM Whitepaper) as the object is moved by the garbage collector and will not change afterwards.

Michael Schmeißer
  • 3,407
  • 1
  • 19
  • 32
0

Yes, it will be constant if you don't override the hashCode method. The default hashCode is the original location of the object in memory. This memory location is retrieved by this method:

System.identityHashCode(Object)

Check out this thread on StackOverflow:

How does the JVM ensure that System.identityHashCode() will never change?

Community
  • 1
  • 1
Martijn Courteaux
  • 67,591
  • 47
  • 198
  • 287
  • 3
    It's not the current location of the object in memory - after all, that can change over time as the garbage collector moves things around. – Jon Skeet Aug 04 '12 at 09:03
  • I'm not sure, to be honest. I've never looked at the implementation details around it :( – Jon Skeet Aug 04 '12 at 09:10
  • *"The default hashCode is the original location of the object in memory."* - not necessarily. See for example: [this previous hotspot implementation](http://hg.printk.org/openjdk6-mips/file/tip/hotspot/src/share/vm/runtime/synchronizer.cpp) which adds some randomness. Just checked open JDK 7 and it looks similar. – assylias Aug 04 '12 at 09:13
  • java doesn't gurantee that it will be constant, it depends on implementation of jvm. – Lokesh Apr 07 '13 at 14:12
0

The default Java implementation of hashcode is based on the pointer to the object, so it should not change when instance variables are changed.

Edit

But Martijn beat me to it.

Steve Jorgensen
  • 11,725
  • 1
  • 33
  • 43