equals(Object obj)有什么作用?

Bes*_*est 13 java

我经常在不同的地方找到一种平等的方法.它实际上做了什么?重要的是我们必须在每个班级都有这个吗?

   public boolean equals(Object obj)
    {
    if (obj == this)
    {
        return true;
    }
    if (obj == null)
    {
        return false;
    }
    if (obj instanceof Contact)
    {
        Contact other = (Contact)obj;
        return other.getFirstName().equals(getFirstName()) &&
                other.getLastName().equals(getLastName()) &&
                other.getHomePhone().equals(getHomePhone()) &&
                other.getCellPhone().equals(getCellPhone());

    }
    else
    {
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

Boz*_*zho 33

它重新定义了对象的"平等".

默认情况下(在定义中java.lang.Object),只有当对象是同一个实例时,它才等于另一个对象.但是,当您覆盖它时,您可以提供自定义相等逻辑.

例如,java.lang.String通过比较内部字符数组来定义相等性.这就是为什么:

String a = new String("a"); //but don't use that in programs, use simply: = "a"
String b = new String("a");
System.out.println(a == b); // false
System.out.println(a.equals(b)); // true
Run Code Online (Sandbox Code Playgroud)

即使您可能不需要像这样测试相等性,您使用的类也可以.例如,实现List.contains(..)List.indexOf(..)使用.equals(..).

检查javadoc以获取该equals(..)方法所需的确切合同.

在许多情况下,当覆盖时,equals(..)您还必须覆盖hashCode()(使用相同的字段).这也是在javadoc中指定的.


Jon*_*Lin 12

对于使2个对象"相等"的不同,不同的类具有不同的标准.通常,如果equals()是相同的Object,则返回true:

Object a = new Object();
Object b = new Object();
return(a.equals(b));
Run Code Online (Sandbox Code Playgroud)

这将返回false,尽管它们都是"对象"类,但它们不是同一个实例.a.equals(a)将返回真实.

但是,在类似String的情况下,您可以有2个不同的实例,但字符串相等性基于构成这些字符串的文字字符:

String a = new String("example");
String b = new String("example");
String c = new String("another");
a.equals(b);
a.equals(c);
Run Code Online (Sandbox Code Playgroud)

这些都是String的不同实例,但是第一个equals将返回true,因为它们都是"example",但第二个不会因为"example"不是"another".

只有当存在相等的特殊情况时,您才需要为每个类重写equals(),例如包含3个字符串的类,但只有第一个String用于确定相等性.在您发布的示例中,可能有另一个字段,description对于2个不同的"联系人"可能有所不同,但如果这4个条件匹配(第一个/最后一个名称和家庭/手机号码),则2个"联系人"将被视为相等),匹配或不匹配的描述不会影响2个联系人是否相等.


nd.*_*nd. 9

除了Bozho提供的所有内容之外,还有一些其他事项需要注意,如果重写等于:

  • 事情.equals(null)必须始终返回false -即空不等于别的.在您的代码的第二个if中处理此要求.

  • 如果确实某些东西 == 别的东西,那么其他.equals(东西)也必须是真的.(即相同的对象必须相等)代码的第一个if处理这个问题.

  • .equals对于非null对象应该是对称的,即a.equals(b)应该是相同的b.equals(a).有时,如果您在父类和子类中进行子类化和重写equals,则此要求会中断.通常equals包含类似的代码if (!getClass().equals(other.getClass())) return false;,至少可以确保不同的对象类型彼此不相等.

  • 如果你覆盖equals你也必须覆盖hashCode,使得以下表达式成立:if (a.equals(b)) assert a.hashCode() == b.hashCode().即两个彼此相等的对象的哈希码必须相同.请注意,反之亦然:具有相同哈希码的两个对象可能彼此相同也可能不相同.通常,通过从用于确定对象相等性的相同属性派生hashCode来处理此要求.

在您的情况下,hashCode方法可以是:

public int hashCode() {
  return getFirstName().hashCode() +
    getLastName().hashCode() +
    getPhoneHome().hashCode() +
    getCellPhone().hashCode();
}
Run Code Online (Sandbox Code Playgroud)
  • 如果你实现Comparable比较两个对象,如果它们相互之间更小,更大或相等,a.compareTo(b) == 0那么当且仅当它是a.equalTo(b) == true

在许多IDE(Eclipse的例如,IntelliJ IDEA的,NetBeans的),有产生这两种功能equals,并hashCode为您,从而省去您的繁琐和可能容易出错的工作.