Effective Java -- 重写equals方法时总要重写hashCode方法

在Java的Object 的规范中,有一点说的是—— 相等的对象必须有相等的散列码(hashCode

通俗的说就是如果两个对象通过equals() 方法比较得到的结果是相等的,那么这两个对象的hashCode 就一定是相等的。

如果我们重写了一个对象的equals() 方法的时候没有重写其相应的hashCode() 方法,就会违反这一约定,如下的测试代码

package com.blog.effective.note9;

/**
 * 〈一个简单的电话号码类〉<br>
 *
 * @author 未绪
 * @time 2018/1/2 15:50
 */
public class PhoneNumber {

    private static String phoneNumber;       //电话号码
    private static String numAddr;          //电话号码的归属地

    public PhoneNumber(String phoneNumber,String numAddr){
        this.phoneNumber=phoneNumber;
        this.numAddr=numAddr;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof PhoneNumber){
            PhoneNumber phoneNumber=(PhoneNumber)obj;
            return this.phoneNumber==phoneNumber.phoneNumber&&this.numAddr==phoneNumber.numAddr;
        }
        return false;
    }
}

如上是一个简单的有段电话号码类,其中包含号码(phoneNumber)和归属地(numAddr)两个属性,并且我们重写了它的equals() 方法

我们来测试一下

    public static void main(String[] args) {

        PhoneNumber phoneNumber1 = new PhoneNumber("123", "FZ");
        PhoneNumber phoneNumber2 = new PhoneNumber("123", "FZ");

        System.out.println(phoneNumber1.hashCode());        //621009875
        System.out.println(phoneNumber2.hashCode());        //1265094477

        System.out.println(phoneNumber1.equals(phoneNumber2));//true

    }

看到输出就知道这是违反了开始所说的Object 类的通用约定。

那么如果就像上面这样写会有什么危害呢?—— 无法与所有的基于散列的集合一起正常使用

如下我们要实现一个根据电话号码来查询相关的用户的功能

        HashMap<PhoneNumber, String> hashMap = new HashMap<>();

        PhoneNumber number = new PhoneNumber("123", "FZ");
        hashMap.put(number,"张三");

        hashMap.get(new PhoneNumber("123","FZ"));

按照道理来说我们期望的返回结果是张三,然而实际运行的结果确实null
这就是因为这两者的hashCode 是不相同的,所以从基于散列的集合中查询不到数据。

所以我们就要根据当前类的属性值来生成其对应的hashCode ,确保当equals() 方法返回的为true 的情况下,其散列值也相同。

有关如何简单的生成一个这样的散列值,将在下一篇博客中说明。

猜你喜欢

转载自blog.csdn.net/zjq_1314520/article/details/78953359