【问题标题】:Implementing multiple equals methods for a single class为单个类实现多个 equals 方法
【发布时间】:2016-09-27 21:08:16
【问题描述】:

我有课说

class Dog {
    String name;
    int age;
    String collarType;
}

我已经重写了 equals 方法来比较所有 3 个字段以确定 2 只狗是否相等。

现在我有 2 个 Dog 对象,即使 2 个 Dog 实例中的 collarType 不同,它们也可以相等。因此,我不能使用我的equals 方法。

使用新架构编写比较器(仅比较姓名和年龄)并检查 compare(Dog d1, Dog d2) 是否返回 0 是最好的方法吗?

【问题讨论】:

  • 出于什么目的需要知道它们是否相等?
  • Guava 有一个名为Equivalence 的类,可以用于此目的。
  • 对我来说这似乎是倒退的:平等测试应该只使用不变的字段,例如姓名(更改的可能性很小)、出生日期(而不是更容易更改的年龄),而不是 colType可以随心所欲地改变。
  • 这取决于您想要比较 Dog 实例的上下文。如果您想使用集合或类似方法对它们进行排序,那么实现比较器是可行的方法。如果你只需要一个额外的equals方法,只需将其实现为Dog的实例方法即可。当然,只有原始的equals 方法可以使用==,你必须用它的名字来调用你的第二个equals:dog1.equalByNameAndAge(dog2) 或类似的。
  • @gmazlami 澄清一下,Java 中的 == 运算符从不“调用” .equals() 方法。 == 比较对象引用或原语。

标签: java equals comparator


【解决方案1】:

正如您所注意到的,平等对用户来说是主观的。但是,唯一“正确”的实际相等应该是对象上的相等(并且它可能是完全等价的,因为不那么严格的版本是正确的会很奇怪)。这等于应该说,在任何情况下,无论对象 1 和对象 2 是否相等,都不可能(以任何方式想象)是不同的。

其他('主观')equals方法应该通过比较器来实现,是的,我认为你应该使用比较器。此外,您应该适当地命名该比较器(如 NameAndAgeComparator),以区分它们,因为您可能还设想 DogRaceComparator 和 SizeComparator 按大小排序。

您可以(可能)为您的比较器提供一个静态的 equals 方法,这样您就可以使用像 equals(dog1,dog2) 这样的静态导入来引用它。但这只是我的 2 美分

【讨论】:

    【解决方案2】:
    • 如果您将其放到任何类型的 Map 或 Set 中,请实现 equals 和哈希代码。
    • 如果要对它们进行排序,请实现 Comparable 接口,但它应该与实现的 equals 和 hashcode 方法兼容。
    • 如果您想按 equlas 和 hashcode 方法以外的其他字段对列表进行排序/比较,请使用 Comparator 实现。

    【讨论】:

      【解决方案3】:

      你的班级应该是这样的:

      class Dog 
      {
          final String name;
          final Integer age;
          final String collarType;
      
          public boolean equals(Object other) 
          {
             return this.name.equals(other.name) && 
                    this.age.equals(other.age) &&
                    this.collarType.equals(other.collarType);
          }
      }
      

      如果这些属性中的任何一个是可变的,那么这会将您的问题归入一个更明显的类别。

      如果这些字段中的任何一个与 equals 无关,则应该是不同的 Type

      public interface Named() { public String name(); } 公共接口 Aged() { 公共字符串年龄(TimeUnit timeUnit); } 公共接口 Collarable { 公共字符串collarType(); }

      那么你有:

      public class Dog implements Named, Aged, Collarable { /* brevity */ }
      

      并提供自然这些接口的Comparator<Named>Comparator<Aged>Comparator<Collarable>实现。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多