4 ms·
Stated another way: The contract Object.hashCode() does not require a stable results between processes; it _only_ requires a stable result during a single run
by rickmode 14y ago
Stated another way:
The contract Object.hashCode() does not require a stable results between processes; it _only_ requires a stable result during a single run of an application.
So if you need a stable distributed hash, the article recommends using a different method than Object.hashCode(), for instance DistributedObject.stableHash(). Using Object.hashCode() can bite you since not all implementations will have stable over multiple runs.
- cbsmith 14y ago...except that there is nothing that prevents you from having a stricter contract on hashCode() with your hashed objects... like EVERY SYSTEM does.
- lmm 14y agoBut not e.g. protobuf. So don't write a distributed routing framework that assumes hashCode() is stable - if you do, it will work fine for Strings and HashMaps and all the standard java objects, and then fail when someone tries to use it with protobuf objects.
- cbsmith 14y agoI ended up posting something much longer on this: http://news.ycombinator.com/item?id=4131326 http://news.ycombinator.com/item?id=4131326 Your comment qualifies as being "wrong", because of one part: "...it will work fine for Strings and HashMaps and all the standard java objects...". In fact hashCode() is stable for a very small subset of the types that ship with standard Java, and even in some of those cases there are caveats. Arrays come pretty standard with Java, but... boolean alwaysFalse(int[] a) { return a.hashCode() == a.clone().hashCode(); }
- lmm 14y agoa.clone().equals(a) is false too; you can't use Array as a thing to route on any more than you can use Object. The point is that in standard java objects with value semantics have stable hashCode implementations, and this is not true in general (And FWIW arrays are a weird corner of Java as far as I'm concerned; every codebase I've worked on avoids them as much as possible)
- cbsmith 14y ago> a.clone().equals(a) is false too. a.clone().equals(a) HAS to be false in that case. It's more than a bit of a given if a.hashCode() != a.clone().hashCode(). > you can't use Array as a thing to route on any more than you can use Object Oh, sure you can. You just need to use java.util.Arrays's methods for "equals" and "hashCode" (or potentially deepHashCode). Also, ArrayList does work. Yes, that is totally F'd up. > The point is that in standard java objects with value semantics have stable hashCode implementations, and this is not true in general Value semantics are pretty rare in Java. I'm not even sure what you really mean there. Pass-by-value is doesn't happen with Java objects. I could see you referring to immutable types, but that doesn't include any of the collection classes. I'm guessing you mean "primitive type wrappers and collections". It'd make more sense if you said something like, "pretty much anything that overrides Object.equals(Object)"... because that's the way it is supposed to work. They are rare in standard class library, because there is little business logic there. In practice, anything that resembles an identifier, and therefore all keys, tends to do the override though. Indeed, most of what people tend to call "business objects" tend to do the override. That's why the convention is there. Most importantly: almost all overrides do so in a fashion that is stable across processes. That's also why distributed frameworks can and should employ the convention/protocol. That equals/hashCode methods in Object are following the Smalltalk trick of having protocol defined in Object even though you shouldn't really use it without subclassing. The Object method isn't a "reference implementation" of the protocol, but rather a placeholder (one they forgot to override in Array objects, and then tried to backdoor in with java.util.Arrays).
- lmm 14y agoI mean value semantics in the standard sense, http://en.wikipedia.org/wiki/Value_semantics http://en.wikipedia.org/wiki/Value_semantics . You're correct that relatively few classes in the java standard library do so. There is no convention that hashCode() should be stable across processes; the only thing that could reasonably define such a convention is the javadoc of Object#hashCode, which explicitly states otherwise. More pragmatically, there is an important set of objects, widely used in distributed systems, whose implementation of hashCode() is not stable across processes (namely protocol buffers objects). So distributed frameworks can't and shouldn't assume hashCode() is stable across processes.