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

在每一个覆盖equals方法的类中,也必须覆盖hashCode方法。不然,会违反Object.hashCode的通用约定,从而致使该类没法结合全部基于散列的集合一块儿正常工做,包括HashMap,HashSet,Hashtbale。ide

下面咱们先看下hashCode约定内容:性能

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

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

  3.若是两个对象根据equals(Object)方法比较是不等的,那么这两个对象的hashCode返回值不必定不等,可是给不一样的对象产生大相径庭的整数结果,能提升散列表的性能。spa

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

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方法从另一个散列桶中查找这个对象,这显然是没法找到的。code

  

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

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

  

相关文章
相关标签/搜索