为什么重写equals而不是使用其他方法名称

时间:2015-01-21 10:20:49

标签: java

这似乎是一个愚蠢的问题,但为什么我们覆盖equals方法而不是使用新名称创建新方法并使用它进行比较?

如果我没有覆盖equals,那意味着==和equals都检查两个引用是否都指向相同的内存位置?

7 个答案:

答案 0 :(得分:57)

  

这似乎是一个愚蠢的问题,但为什么我们覆盖equals方法而不是使用新名称创建新方法并使用它进行比较?

因为所有标准集合(ArrayListLinkedListHashSetHashMap,...)在决定两个对象是否相等时使用equals

如果你发明了一种新的方法,这些收藏品就不会知道它而不能按预期工作。

以下内容非常重要:如果ArrayList调用Object.equals等集合,则此调用将在运行时解析为重写方法。因此,即使您发明了集合不知道的类,它们仍然可以在这些类上调用方法,例如equals

  

如果我没有覆盖equals,那意味着==和equals都检查两个引用是否都指向相同的内存位置?

是。 Object.equals的实施仅执行==检查。

答案 1 :(得分:9)

如果您使用依赖于等号的类,则覆盖等于,例如HashMapHashSetArrayList等等。

例如,如果您将类的元素存储在HashSet中,则必须覆盖hashCodeequals,如果您希望元素的唯一性不是通过简单的引用相等来确定的

是的,如果你不重写equals,默认等于实现(在Object类中实现)与==相同。

答案 2 :(得分:5)

除了主要原因,已在其他答案中给出,请考虑程序可读性。

如果您覆盖equalshashCode,那么阅读代码的人都知道这些方法的用途。这样做会告诉读者您的类实例之间的值相等的标准。阅读使用equals的代码的人会立即知道您正在检查值是否相等。

如果您使用其他名称,它只会让读者感到困惑,并且会花费额外的时间阅读您的JavaDocs,以了解您的方法的用途。

答案 3 :(得分:4)

因为equals()Object类的一个方法,它是所有类的超类,并且由于它本身存在于您编写的每个类中。因此,每个集合类或其他标准类都使用equals()进行对象比较。如果希望其他类支持自定义类对象的相等性,则必须仅覆盖equals()(因为其他类知道对象比较调用equals())。如果您只使用自己的类,则可以创建一个新方法,并确保所有内容都使用自定义方法进行比较。

答案 4 :(得分:2)

equals和hashcode方法是特殊的方法,广泛用于java的实用程序类,特别是集合框架,以及wrpper类,例如: String,Integer已覆盖此方法,例如,如果你在HashSet中放置任何你选择的具有正确的equals和hashcode实现的Object,为了保持唯一性的属性,hashcode将与hashset中的所有现有对象进行比较,如果它找到任何hashcode匹配,那么它看起来进入equals方法,仔细检查两者是否真的相等,如果同等检查也通过,那么传入的对象被拒绝,但是如果没有传递hashcode相等性检查,那么hashset将不会用于equals方法并直接放置该对象进入hashset。所以我们需要确保equals和hashcode的实现在逻辑上是正确的。

答案 5 :(得分:2)

HashMap<T,U>这样的类需要有一些方法来识别集合中的哪个项目(如果有的话)应被视为等同于给定项目。有两种通用方法可以实现:

  1. 要求存储在集合中的任何内容必须包含执行此类比较的虚拟方法(并且最好提供指定部分等价类的快速方法(例如hashCode())。

    < / LI>
  2. 要求创建集合的代码必须提供一个对象,该对象可以接受对其他对象的引用并对它们执行与等效相关的操作。

  3. 可以省略equals中的hashCode()Object,并且类似HashMap的类型只能用于实现equatable的密钥类型包含此类成员的接口;希望使用由身份键入的引用集合的代码必须使用IdentityHashMap。这样的设计不会是不合理的,但是现在的设计使得使用HashMap的通用集合类型可以用于按价值和身份进行比较的事物,而不必为HashMap集合和IdentityHashMap集合定义单独的类型。

    另一种设计可能是GeneralHashMap类型,其构造函数需要指定比较函数,并且IdentityHashMapHashMap都来源于此;后者会将其类型约束为equatable,并将其标识函数链与其中包含的对象链接。该设计可能没有什么特别的错误,但事情并非如此。

    在任何情况下,都需要有一些标准手段,通过这些手段,集合可以识别应被视为等同的项目;使用虚拟equals(Object)getHashCode()是一种方法。

答案 6 :(得分:1)

  

问题1

有两件事。 equals()位于Object类中 在比较对象时使用equals()hashcode()方法的集合框架

  

问题2

是比较两个对象。但是当你使用equals()比较两个字符串对象时,它只检查值。