【问题标题】:Does Java have something like Hashable, Hasher?Java有Hashable、Hasher之类的东西吗?
【发布时间】:2020-01-10 16:58:24
【问题描述】:

对于Hash数据结构,比如HashSet、HashMap等,我们需要实现hashcode。但是,这不是很方便。我们可以改用 Hashable 或 Hasher 之类的东西吗?

以下是 Swift 中的示例: https://developer.apple.com/documentation/swift/hashable

【问题讨论】:

标签: java hashmap hashcode hashable


【解决方案1】:

在Java中,基本上有多种方式:

  • 您只需“保留”您从 Object 继承的 hashCode() 方法(这不是一个很好的选择,因为它会忽略您的字段)
  • 您使用Objects.hashCode() 计算字段的哈希值,然后在自定义类中为hashCode() 执行@Override 时使用它。正如用户 Andreas 所指出的,此解决方案的一个缺点是在将这种方法用于原始类型值时会自动装箱。
  • 您也可以使用 Apache Commons HashCodeBuilder。最大的优势:该类自动使用反射来检索所有字段值以进行散列。缺点:反射容易出错,并且会对性能产生重大影响。但这仍然是一个有趣的选择,例如在处理“数据持有者”又名“bean 类”时,它们基本上只是带有 getter 和 setter 的字段的容器。

除此之外:您当然可以为您需要的每个类覆盖hashCode(),并“手动”从您的字段中计算哈希值。或者告诉您的 IDE 为您执行此操作。

最后,更进一步,JVM 平台允许像 Lombok 这样的库在编译阶段自动插入这样的方法覆盖。甚至可以为 JVM 使用其他语言,例如带有 data classes 的 kotlin。

【讨论】:

  • 不是反对者,我自己会用Objects.hashCode() 回答,但你打败了我。我对Objects.hashCode() 的唯一问题是 GC 开销,即基元和可变参数数组的自动装箱,这就是为什么我仍然更喜欢“手动”执行此操作的原因。或者,也许我只是一个不愿改变自己方式的老顽童。
  • 另请注意,IDE 倾向于为您生成一个。
  • (另外,Lombok 和类似的工具也值得一提。)
  • 根据我的经验,使用每个非静态字段来计算哈希码几乎不是我们想要的行为,因为身份通常由一个或几个主键字段定义,所以 Lombok 和Apache Commons 是糟糕的选择。 Objects.hash(用于多个字段)和 Objects.hashCode(用于单个字段)几乎总是最佳选择。自动装箱不太可能是一个明显的惩罚,特别是考虑到自动装箱的值被缓存。
  • @chrylis 好点。也“借”了它们作为我的答案。谢谢!
猜你喜欢
  • 2011-05-25
  • 1970-01-01
  • 2015-11-03
  • 2011-12-29
  • 1970-01-01
  • 2011-08-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多