【问题标题】:Why Entry interface defines methods like equals and hashCode?为什么Entry接口定义了equals和hashCode之类的方法?
【发布时间】:2017-08-12 08:30:11
【问题描述】:

我看到接口 java.util.Map.Entry 有方法:

boolean equals(Object o);
int hashCode();

当相同的方法从Object类继承时,为什么上述方法是Entry接口的一部分?

感谢和问候, 拉胡尔

【问题讨论】:

  • 因为他们需要有不同的实现?有记录吗?
  • 我没有看到任何将问题标记为 down 的正当理由? Node 实现了 Map.Entry 并且它可以覆盖 equals 和 hashCode,即使它没有在 Entry 接口中声明?我的问题很简单,在 Entry 界面中声明这些声明的意义何在?
  • 我已经回答过了。这是documented为什么。阅读它。
  • @EJP 不,你没有。检查 Map.Entry 界面
  • @EJP 即使您将它们添加到任何接口,您仍然不会被强制覆盖,因为它们是从Object 继承的。 OP 对他的问题的表述很糟糕,但显然不是“我们为什么要覆盖东西”

标签: java hashmap equals hashcode


【解决方案1】:

需要考虑三点:

  • 技术的角度来看,这不是必需的:每个类都从Object 类继承这两个方法。从技术上讲,将这两种方法添加到接口中不会增加任何内容

  • 实现的角度来看:这些定义不会“覆盖”类Object 的定义。因此,您无需编写自己的实现即可实现此接口。

  • 文档的角度来看:Map.Entry.equals()Map.Entry.hashCode() 的文档对这些方法在接口的任何实现中应该做什么有非常具体的要求。

您可以将有关这两种方法要求的文档放入接口的通用文档中,但这会使查找(和阅读)该文档变得更加困难。

理想情况下,查找接口的人会看到它声明了这两个方法,对此感到好奇并阅读这两个方法的接口文档,然后得到一个提示,告诉他应该如何正确地在实现这些方法的类中实现这些方法界面。

【讨论】:

    【解决方案2】:

    正如最重要的定义所说;当从另一个类扩展而来的类想要使用父类的大部分功能并希望在某些情况下实现特定功能时使用它。 boolean equals() 的 oracle 文档说;

    这可确保 equals 方法在 Map.Entry 接口的不同实现中正常工作。

    所以对于equals()方法的具体实现,boolean equals(Object o)int hashCode()被覆盖了。

    【讨论】:

    • 这不是问题的答案。 OP 知道覆盖是如何工作的,但他不明白为什么在另一个接口中重复方法签名,因为它们来自 Object
    • 根据您的回答“这可确保 equals 方法在 Map.Entry 接口的不同实现中正常工作。”如果我从 Entry 接口中删除 hasCode 和 equals 方法声明,请告诉我会出现什么问题。
    • 先生,正如文档中所说,对于 Map.Entry 接口的不同散居地的正确实现以及 Object 类的 equals() 方法具有限制和歧义。
    • @rbhawsar 问题是不再记录他们需要做什么。
    • 我完全同意您的观点,先生(@Ralf Kleberhoff),但我上面提到的运行时行为会模棱两可,因此开发人员也为Map.Entry 接口声明了它
    【解决方案3】:

    只是为了给 Javadoc 留个位置。

    在接口中声明equals()hashCode() 不会强制实现类实现它们中的任何一个。从 Object 继承的方法满足接口的技术要求(但不满足 Maps 中所需的语义)。

    Map.Entry 需要特定的 equals/hashCode 行为,因此 Java 设计人员选择将它们冗余声明为 Map.Entry 接口的一部分,并将 Javadoc 放在那里解释如何正确执行。

    【讨论】:

      【解决方案4】:

      有一个经验法则,如果你要覆盖其中一个方法(即equals()或hashCode()),你必须同时覆盖它们,否则就是违规为 equals() 和 hashCode() 订立的合同。该方法的约定请参考Oracle's java doc

      因此,Entry 接口为特定功能覆盖了这两种方法。

      此外,如果你(或入口接口)不重写类的equals()方法,

      您将无法将这些对象用作 hashtable

      中的 key

      而且你可能不会得到准确的 Sets 以至于没有 概念上的重复。

      还有,

      Object 类中的 equals() 方法仅使用 == 用于比较的运算符,因此除非您覆盖 equals(),否则两个对象 仅当两个引用引用相同时才被视为相等 对象。

      如果你查看 Object 类的源代码,你会发现以下 equals() 方法的代码。

        public boolean equals(Object obj) 
      {
          return (this == obj);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-07-22
        • 2011-05-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-28
        • 1970-01-01
        相关资源
        最近更新 更多