【问题标题】:Java: Automatic equals() and hashCode()Java:自动 equals() 和 hashCode()
【发布时间】:2011-08-05 16:10:29
【问题描述】:

为简单的数据 POJO 实现 equals()hashCode() 会使我的代码变得混乱,并且维护起来很乏味。

哪些库会自动处理这个问题?
由于性能原因,我更喜欢字节码检测而不是 AOP 方法。

更新:已经讨论了实现equals()和hashCode()的必要性,这是我的观点:

用最少的努力提前完成,而不是在代码中挖掘,在涉及到它时添加 hC/eq 不是更好吗?

【问题讨论】:

  • 没有库可以为您处理equals - 只有您知道什么使两个对象相等。您使用的哪个 IDE 不会为您生成 hashCode?为什么要对equalshashCode 进行如此多的维护?
  • 我知道在 Java 社区中,为基本上每个 POJO 实现这些方法是很常见的,但我不得不问:您实际上是否将所有 POJO 类型用作哈希表中的键?你在比较它们是否平等?如果不是,那为什么还要麻烦呢?
  • @Paul - NetBeans,它会生成;只是,我每次都必须重新生成,而且它会产生 10 行代码。另外,lib在生成的时候可以使用反射,为什么不能处理equals呢?
  • @Dan - 好吧,我不知道,但是各种框架都可以 - 例如网络框架。在使用了许多范例的应用程序中,跟踪什么实例在何时何地获得可能是困难的——请求之间的组件中的所有缓存、注入、序列化......
  • @VlastimilOvčáčík 是的,我认为从上下文中可以清楚地看出:我更喜欢 Lombok 方式而不是 AOP 方式。

标签: java equals hashcode


【解决方案1】:

Project Lombok 提供注解@EqualsAndHashCode,它将为您的Java 类生成equals()hashCode()。当然,与手动实现这些方法相比,存在一些缺点,因此请务必阅读链接页面上的“小字”。

【讨论】:

  • 这可能就是我想要的。只可惜它没有与 NetBeans 集成。
【解决方案2】:

Java 7 及更高版本

虽然不是您要求的灵丹妙药,但从 Java 7 及更高版本开始,编写 hashCode 覆盖现在要容易一些。

Objects.hashCode & Objects.hash

从 Java 7 开始,Objects 类提供了一些用于生成哈希码值的实用方法。

有关更多讨论,请参阅my Answer 相关问题。

单个成员,不容忍 NULL

@Override
public int hashCode() {
    return this.member.hashCode() ;  // Throws NullPointerException if member variable is null.
}

单个成员,容忍 NULL

@Override
public int hashCode() {
    return Objects.hashCode( this.member ) ;  // Returns zero (0) if `this.member` is NULL, rather than throwing exception.
}

多成员

@Override
public int hashCode() {
    return Objects.hash( this.memberA , this.memberB , this.memberC  ) ;  // Hashes the result of all the passed objects’ individual hash codes.  
}

【讨论】:

    【解决方案3】:

    您可以使用 Google 的 AutoValue 库自动生成具有 equalshashCode 的不可变值类。这些值类有点类似于 Scala 的案例类或由 Lombok 生成的类。

    还有一个post 介绍如何在 IDE 中使用它。

    【讨论】:

      【解决方案4】:

      【讨论】:

      • 不...但感谢您让我最终检查它的功能。
      【解决方案5】:

      Apache commons-lang 库有一个 HashCodeBuilder 和 EqualsBuilder 可以为您完成一些工作并缩短这些方法。甚至还有反射版本可以根据 POJO 中的字段为您完成所有工作。但是,我不建议这样做。反射可能很慢(尽管不像许多人想象的那么糟糕),您应该实施它们以确保只有正确的字段被认为是相等的。

      我的问题是,你真的需要这样做吗?通常 POJO 上的 hashcode 和 equals 只需要与 Maps 或 Sets 一起使用。在 Maps 的情况下,通常您会使用 ID 作为键,而不是 Pojo 本身。所以,....你是在为自己工作吗?

      【讨论】:

      • 第 2 段 +1,但是用最少的努力提前完成,而不是在代码中挖掘,在涉及到它时添加 hC/eq 不是更好吗?
      • 就像所有事情一样,它最终是一种权衡。如果预先完成它很好,但是在实际需要时实施它并没有证明我的经验过于困难。当然,我通常有测试告诉我什么时候我错过了实现它。 :)
      猜你喜欢
      • 2019-06-02
      • 1970-01-01
      • 2011-07-09
      • 2011-02-13
      • 1970-01-01
      • 2021-10-31
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      相关资源
      最近更新 更多