代码之家  ›  专栏  ›  技术社区  ›  N8g

覆盖equals方法与创建新方法

  •  21
  • N8g  · 技术社区  · 17 年前

    我一直认为应该重写java中的.equals()方法,使其特定于您创建的类。换句话说,寻找两个不同实例的等价性,而不是两个对同一实例的引用。然而,我遇到了其他程序员,他们似乎认为应该保留默认对象行为,并创建一种新方法来测试同一类中两个对象的等价性。

    支持和反对重写equals方法的理由是什么?

    7 回复  |  直到 9 年前
        1
  •  19
  •   McDowell rahul gupta    17 年前

    如果要测试标准库类中的等价性(例如,确保java.util.Set包含唯一元素或在java.util.Map对象中使用对象作为键),则必须重写equals方法。

    请注意,如果覆盖等于,请确保遵守API合同,如文档中所述。例如,确保您也覆盖 Object.hashCode :

    如果两个对象相等,则根据 equals(Object)方法,然后 在每个对象上调用hashCode方法 这两个对象必须产生相同的结果 整数结果。

    编辑:我没有把这篇文章作为关于这个问题的完整答案发表,所以我会附和Fredrik Kalseth的说法,即压倒一切的平等最适合 immutable objects .引用API Map :

    注意:如果 可变对象被用作映射键。 未指定映射的行为 如果对象的值发生了变化 以一种影响平等的方式 当对象是关键时进行比较 在地图上。

        2
  •  8
  •   David Schlosnagle    17 年前

    我强烈建议你拿起一本《Effective Java》,按照以下要求阅读第7项 equals contract 。如果要为可变对象覆盖equals,则需要小心,因为许多集合(如Maps和Sets)都使用equals来确定等价性,并且更改集合中包含的对象可能会导致意外的结果。布莱恩·戈茨也有一个相当不错的 overview of implementing equals and hashCode .

        3
  •  4
  •   Fredrik Kalseth    17 年前

    你应该“永远”不覆盖equals&getHashCode用于可变对象-这适用于.net和Java。如果你这样做,并使用这样的对象作为f.ex字典中的键,然后 变化 对于该对象,您将遇到麻烦,因为字典依赖于hashcode来查找该对象。

    这里有一篇关于这个主题的好文章: http://weblogs.asp.net/bleroy/archive/2004/12/15/316601.aspx

        4
  •  2
  •   Community Mohan Dere    9 年前

    @大卫·施洛斯纳格尔 mentions 提到乔什·布洛赫的 Effective Java --这是一个 必读的 对于任何Java开发人员来说。

    还有一个相关的问题:对于不可变值对象,您还应该考虑重写 compare_to 。如果它们不同,标准措辞是 Comparable API :

    通常情况是这样的,但并不严格要求(比较(x,y)==0)==(x.equals(y))。一般来说,任何违反这一条件的比较器都应该明确指出这一事实。建议的语言是“注意:此比较器施加的顺序与等号不一致。”

        5
  •  0
  •   juan    17 年前

    Equals方法旨在比较参考文献。因此,改变其行为不应被高估。

    如果需要,您应该创建一个新方法来测试不同实例中的等效性(或在某些.NET类中使用CompareTo方法)

        6
  •  0
  •   serg10    17 年前

    说实话,在Java中,并没有真正反对重写的论点 同等的人 。如果你需要比较实例的相等性,那么这就是你要做的。

    如上所述,您需要了解与 散列值 ,同样,注意周围的陷阱 Comparable 界面-在几乎所有你想要的情况下 自然排序 如Comparable所定义 与平等一致 (见 BigDecimal 规范反例的api文档)

    除了不使用现有的库类之外,创建一种新的确定相等性的方法在一定程度上违背了Java惯例。

        7
  •  0
  •   naXa stands with Ukraine    11 年前

    您只需要覆盖 equals() 如果您希望在向排序数据结构添加对象时具有特定行为,请使用方法( SortedSet 等等)

    当你这样做时,你也应该覆盖 hashCode() .

    看见 here 以获得完整的解释。