Object类重写equals方法和重写hashcode方法之间的充分必要性

结论

1.equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2.hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
3.重写equals方法,必须重写hashcode方法(因为equals返回true,两个对象的hashcode必须相同);
4.重写hashcode方法,不必重写equals方法。(相当于替换hash算法)

验证

1.针对第3个结论,使用反证法:重写equals,不重写hashcode方法,看看会有什么问题:

public class ObjectTest {
    static class Person {
        private String name;
        private Integer age;

        Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this) return true;
            if (obj != null && obj instanceof Person) {
                Person pobj = (Person) obj;
                if (!Objects.equals(name, pobj.name)) return false;
                return Objects.equals(age, pobj.age);
            }

            return false;
        }
    }

    public static void main(String[] args) {
        Person p1 = new Person("aaa", 12);
        Person p2 = new Person("aaa", 12);
        //此处打印:true
        System.out.println(p1.equals(p2));

        Map<Person, String> map = new HashMap<>();
        map.put(p1, "student");
        //此处打印:null
        System.out.println(map.get(p2));
    }
}

代码分析:
针对p1和p2两个Person对象,第一个打印语句显示,p1.equals(p2);
第二段代码实例化一个hashmap,Person类作为key值,value是字符串类型,此时向map中添加一个entry,key为p1,value为"student",从上一段代码得知,p1.equals(p2),那么以p2作为key理论上应该也可以获得"student"字符串,然而打印结果是null,这表明,p1和p2的hashcode不相等,从而得出结果:equals方法返回true,hashcode却不相等,这与实际是不相符的,所以此时hashCode方法不再满足需要,需要重写。如下(一种写法,非唯一写法):

		@Override
        public int hashCode() {
            int nameHash = name.hashCode();
            return 31 * nameHash + age;
        }

2.针对第4个结论,Object类的equals方法比较的是对象的内存地址,因此,equals相等的对象是同一个内存对象,其hashcode不管使用何种hash算法都是一样的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值