I'd like to be able to determine whether I've encountered an object before - I have a graph implementation and I want to see if I've created a cycle, probably by iterating through the Node objects with a tortoise/hare floyd algorithm.
But I want to avoid a linear search through my list of "seen" nodes each time. This would be great if I had a hash table for just keys. Can I somehow hash an object? Aren't java objects just references to places in memory anyway? I wonder how much of a problem collisions would be if so..
The simple answer is to create a HashSet
and add each node to the set the first time you encounter it.
The only case that this won't work is if you've overloaded hashCode()
and equals(Object)
for the node class to implement equality based on node contents (or whatever). Then you'll need to:
IdentityHashMap
class which uses ==
and System.identityHashcode
rather than equals(Object)
and hashCode()
, orAren't java objects just references to places in memory anyway?
Yes and no. Yes, the reference is represented by a memory address (on most JVMs). The problem is that 1) you can't get hold of the address, and 2) it can change when the GC relocates the object. This means that you can't use the object address as a hashcode.
The identityHashCode
method deals this by returning a value that is initially based on the memory address. If you then call identityHashCode
again for the same object, you are guaranteed to get the same value as before ... even if the object has been relocated.
I wonder how much of a problem collisions would be if so..
The hash values produced by the identityHashCode
method can collide. (That is, two distinct objects can have the same identity hashcode value.) Anything that uses these values has to deal with this. (The standard HashSet
and IdentityHashMap
classes take care of these collisions ... if you chose to use them.)