第9条:覆盖equals时总是覆盖hashCode

本文深入探讨了在Java中hashCode方法与equals方法的正确实现原则。强调了当覆盖equals方法时,hashCode方法也必须被覆盖,以确保类能够正确地在基于散列的集合中工作,如HashMap和HashSet。文章通过实例展示了未覆盖hashCode方法可能导致的问题,并提供了正确的hashCode实现方式。
摘要由CSDN通过智能技术生成

在每个覆盖equals方法的类中,也必须覆盖hashCode方法。否则,会违反Object.hashCode的通用约定,从而导致该类无法结合所有基于散列的集合一起正常工作,包括HashMap,HashSet,Hashtbale。

下面我们先看下hashCode约定内容:

  1.只要对象equals方法的比较操作所用到的信息没有被修改,对同一对象调用多次,hashCode方法都必须返回同一整数。在同一应用程序的多次执行过程中,每次执行返回的整数可以不一致。

  2.如果两个对象根据equals(Object)方法比较是相等的,那么这两个对象的hashCode返回值相同。

  3.如果两个对象根据equals(Object)方法比较是不等的,那么这两个对象的hashCode返回值不一定不等,但是给不同的对象产生截然不同的整数结果,能提高散列表的性能。

如果不覆盖hashCode方法,我们在需要用到hashCode的地方可能不会如我们所愿,下面看个例子,有这么一个类,我们只覆盖了equals方法,没有覆盖hashCode方法:

class MyObject{
    private String field01;

    public MyObject(String field01) {
        this.field01 = field01;
    }
    
    //覆盖equals方法
    @Override
    public boolean equals(Object o) {    
        if (this == o) return true;
        if (o == null || getClass() != o.getClass())
                return false;
        MyObject myObject = (MyObject) o;
        return (field01 == null ? myObject.field01 == null : field01.equals(myObject.field01));
    }
}

public class EffictiveTest {
    public static void main(String[] args) {
          Map<MyObject, String> map = new HashMap<>();
          map.put(new MyObject("123"), "123");
          System.out.println(map.get(new MyObject("123")));
    }
}

通过运行的结果我们可以看到key是new MyObject("123")时,value是null,从而我们知道即使覆盖了equals方法后还是不能保证相等,原因在于该类违反了hashCode的约定,由于MyObject没有覆盖hashCode方法,导致两个相等的实例拥有不相等的散列码,put方法把此对象放在一个散列桶中,get方法从另外一个散列桶中查找这个对象,这显然是无法找到的。

  

当我们加入hashCode方法后就正确显示结果了。

//至于hashCode方法怎么写,返回的哈希值参考是什么,可以参考:http://blog.csdn.net/zuiwuyuan/article/details/40340355
@Override
public int hashCode() {
     int result = field01.hashCode() * 17;
     return result;
}

  

 

转载于:https://www.cnblogs.com/Tony-Anne/p/6727671.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值