0

For Hash data structures, like HashSet, HashMap, etc., we need to implement hashcode. However, this is not very convenient. Can we use something like Hashable or Hasher instead?

Here is an example in Swift: https://developer.apple.com/documentation/swift/hashable

Augie Li
  • 198
  • 1
  • 1
  • 11

1 Answers1

6

In Java, there are basically multiple ways:

  • you just "keep" the hashCode() method you inherit from Object (not a really great option, as that ignores your fields)
  • you use Objects.hashCode() to compute hashes on fields, to then use that when doing a @Override for hashCode() in a custom class. As pointed out by user Andreas, the one downside of this solution is the auto-boxing detour when using this method for primitive type values.
  • you can also use the Apache Commons HashCodeBuilder. The big advantage: that class automatically uses reflection to retrieve all field values for hashing. The downside: reflection is error prone, and comes with a significant performance impact. But it is still an interesting option, for example when dealing with "data holder" aka "bean classes" that are basically just containers for fields with getters and setters.

Beyond that: you can of course override hashCode() yourself for each class you need to, and "manually" compute hashes from your fields. Or tell your IDE to do that for you.

Finally, going one step further, the JVM platform allows for libraries like Lombok that automatically insert such method overrides during the compile phase. Or even to use other languages for the JVM like kotlin with its data classes.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
  • 1
    Not the down-voter, and I'd have answered with `Objects.hashCode()` myself, but you beat me to it. My only problem with `Objects.hashCode()` is the GC overhead, i.e. autoboxing of primitives and varargs array, which is why I still prefer to do it "manually". Or maybe I'm just a old codger unwilling to change my ways. – Andreas Sep 08 '19 at 20:11
  • Note also that IDEs tend to offer to generate one for you. – chrylis -cautiouslyoptimistic- Sep 08 '19 at 20:32
  • 1
    (Also, Lombok and similar tools are worth mentioning.) – chrylis -cautiouslyoptimistic- Sep 08 '19 at 20:33
  • 1
    In my experience, using every single non-static field to compute a hash code is almost never desired behavior, since identity is usually defined by one or a few primary-key-ish fields, so Lombok and Apache Commons are poor choices. Objects.hash (for multiple fields) and Objects.hashCode (for a single field) are almost always the best choice. Autoboxing is unlikely to be a noticeable penalty, especially considering that autoboxed values are cached. – VGR Sep 08 '19 at 21:34
  • @chrylis good points. "borrowed" them for my answer, too. Thank you! – GhostCat Sep 09 '19 at 02:38
  • @VGR we use the hash/equals/StringBuilder for some of our "bean" classes. So far, it works out nicely. – GhostCat Sep 09 '19 at 02:40