hashCode&equals


1、先看下 equals==

  • == 运算符

    在Java中 == 常用于比较两个基本数据类型的关系(比较的是变量的值)。如果使用 == 比较两个对象(引用类型),那么它比较的是两个对象的内存地址(堆内存)。

  • equals方法(默认由 == 实现)

    public boolean equals(Object obj) {
        return (this == obj);
    }
    

    equals方法是Object类的方法,也就是任何类都可以重写这个方法(每个类都继承自Object类),equals方法的特殊之处就在于此,如果想比较两个对象的内容是否相同,你就可以重写equals方法,并自定义比较规则。

2、再来看一下hashCode()

  • hashCode()

    此方法也是由Object类继承过来

    public native int hashCode();
    

    Object类中的hashCode()方法返回对象在内存中地址转换成的一个int值,所以如果没有重写hashCode()方法,任何对象的hashCode()方法都是不相等的。

  • 为什么需要hashCode这个方法?

    这个方法主要用与对于散列存储的集合中,每次向散列集合中添加数据,集合都会比较当前数据在集合中是否已经存在,如果此时集合的数据量比较大时,使用equals方式比较将会非常耗时,而hashCode方法主要就是解决这个问题的,使用hashCode可以快速的得到数据的哈希码,如果两个对象的哈希码不相等,两个对象一定不相等,此时就可以直接加入。如果两个对象的哈希码相等的情况下(存在哈希冲突的情况,两个不同的对象产生了相同的哈希码),再去调用equals方法比较是否相等,最终是否添加成功由equals的返回值决定。

    如果不重写hashCode,对于相同内容的对象的数据存入散列存储的集合(hashSetLinkedHashSet)中时,还会调用最原始的hashCode,发现他们的hashCode是不相等的,从而将者两个相同内容的对象数据存入集合中,这不是我们期待的情况。

    如果重写equals时,也重写hashCode,再进行上述情况时,对于相同内容的对象,他们的hashCode是相同的(相同对象hashcode一定相同,反之不然),所以添加第二个对象时,就会失败,这也是我们期待的。

3、重写equal方法时,建议重写hashCode

  • hashCode()方法存在的主要目的就是提高效率,但是如果你想把对象放到散列存储结构的集合中时,是必须要重写的。

参考

  • 比较两对象为什么要重写hashCode()方法【建议阅读】

  • 为什么重写equals就得重写hashCode

  • 如何解决哈希冲突的问题?