关于java:Java-中的-equals-和-hashCode-方法

41次阅读

共计 1746 个字符,预计需要花费 5 分钟才能阅读完成。

equals 办法

Object 类的 equals 办法是比拟两个对象的地址是否相等,也就是说所有类的默认 equals 办法都是比拟地址是否相等;所以当须要判断简单对象是否相等时,咱们要重写 equals 办法:

// 例子
@Override
public final class PhoneNumber{
    private short areaCode, prefix, lineNum;

    public boolean equals(Object o){if(o == this)
        return true;
    if(!(o instanceof PhoneNumber))
        return false;
    PhoneNumber pn = (PhoneNumber)o;
    return pn.lineNum == lineNum && pn.prefix == prefix &&pn.areaCode ==         areaCode;
    }
}

留神:

  • 不要将 equals 参数类型 Object 改为其余的类型,否则将重载 (Overload) Object.equals 而不是笼罩 (Override) Object.equals
  • equals 办法应该满足自反性、对称性、传递性、一致性(如果没有批改,必须放弃相等)和非空性(任何对象不能等于 null,instanceof 关键字能够查看)。

hashCode 办法

哈希码有一个通用约定:

  • 一个对象屡次调用 hashCode 办法都应该返回雷同的值;
  • 两个对象通过 equals 办法比拟返回 true,则它们的 hashCode 肯定相等,也就是说相等的对象必须具备相等的散列码 (hash code);
  • 两个对象的 hashCode 相等,那么两个对象不肯定相等;
  • 一个好的散列函数(hashCode)通常偏向于为不相等的对象产生不相等的散列码,这样能够进步哈希表的性能;

在判断两个对象是否相等时,会 先判断 hashCode 是否相等 ,如果 hashCode 不相等则认为两个对象不相等;如果 hashCode 相等再进行 equals 办法比拟; 这是因为 hashCode 办法比 equals 办法效率高,当咱们要判断 Set 汇合是否存在某一个对象时,先定位到 hashCode 对应的哈希桶里寻找,如果没有对象则阐明不存在该对象,如果有对象再用 equals 办法判断,大大提高了查找效率;(HashSet 底层是用 HashMap 实现的)

为什么重写 equals 办法时必须重写 hashCode 办法?

Object 类的 equals 办法比拟两个对象的地址是否相等,hashCode 办法是一个本地办法,返回一个由对象的地址转换失去的值,所以如果咱们重写了 equals 办法,但没有重写 hashCode 办法,这样的话当两个对象通过 equals 比拟的后果是相等的,然而因为它们的 hashCode 不同,所以 Java 判断它们是不相等的两个对象,也就能够同时放到 HashSet 中,这就导致了谬误的产生;

hashCode 怎么重写?

  1. 申明一个 int 类型变量 result,初始化为对象中第一个要害域的散列码(要害域指影响 equals 比拟的域),按步骤 2.a 中的计算方法;
  2. 对剩下的每一个要害域 f 实现以下步骤:

    a. 计算该域 int 类型的散列码 c:

    • 该域是 根本类型,散列码为 Type.hashCode(f),Type 为对应的装箱类型;
    • 该域是 对象援用,如果为 null,返回 0,否则调用这个对象的 hashCode 办法;
    • 该域是 数组类型,对数组的每个重要的元素计算一个散列码而后用 2.b 中的办法组合起来。如果数组中所有元素都重要,能够应用 Arrays.hashCode() 办法。

b. 依照公式将 2.a 中失去的散列码合并到 result 中:

result = 31 * result + c;

例子:

@Override
public int hashCode(){int result = Short.hashCode(areaCode);
    result = 31 * result + Short.hashCode(prefix);
    result = 31 * result + Short.hashCode(lineNum);
    return result;
}

参考资料:

  1. hashCode 原理剖析
  2. hashCode 源码
  3. 「Effective Java 第三版」
  4. 面试官:为什么重写 equals 时必须重写 hashCode 办法?
  5. Java equals 办法详解

正文完
 0