美文网首页
Java基础-equals()和hashCode()

Java基础-equals()和hashCode()

作者: 若一爸爸 | 来源:发表于2019-03-02 22:25 被阅读0次

1.equals()和hashCode()干嘛的?

equals(Object obj)返回该对象是否与参数对象“相等”,Object类的equals方法实现如下,即基本类型是值比较,引用类型是内存地址比较。Object类中equals()方法实现如下:

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

hashCode()返回该对象的哈希码值,在哈希表中起作用,以提高集合的查找效率,例如HashSet,HashMap

2.equals()和hashCode()有何联系?

JDK中对equals()方法和hashCode()方法之间的联系做了说明:

  • 如果两个对象使用equals()方法判断为相等,则hashCode()方法也应该相等。

为何这样规定?
以HashMap为例,HashMap底层以数组和链表结构存储数据,如图所示:


114006_HzFL_2927759.png

HashMap的put()方法根据键对象的hashCode()方法计算其哈希码,从而确定该键值对在数组中的位置,再根据键对象的equals()判断链表中是否有相同对象,最后选择是否插入该对象,而get()方法也是先调用键对象的hashCode()确定数组位置再通过equals()方法逐一在链表中寻找对象。
由此可知,如果两个键对象hashCode()不相等,那么它们会被存储在“数组”的不同位置。规定“两个对象使用equals()方法判断为相等,则hashCode()方法也应该相等”可以避免在类似HashMap这样的集合中存储两份相同对象的可能。

3.equals()和hashCode()如何重写?

参考博文
《Effective Java》中提出了一种简单通用的hashCode算法
A、初始化一个整形变量,为此变量赋予一个非零的常数值,比如int result = 17;
B、选取equals方法中用于比较的所有域(之所以只选择equals()中使用的域,是为了保证上述原则),然后针对每个域的属性进行计算:
(1) 如果是boolean值,则计算f ? 1:0
(2) 如果是byte\char\short\int,则计算(int)f
(3) 如果是long值,则计算(int)(f ^ (f >>> 32))
(4) 如果是float值,则计算Float.floatToIntBits(f)
(5) 如果是double值,则计算Double.doubleToLongBits(f),然后返回的结果是long,再用规则(3)去处理long,得到int
(6) 如果是对象应用,如果equals方法中采取递归调用的比较方式,那么hashCode中同样采取递归调用hashCode的方式。否则需要为这个域计算一个范式,比如当这个域的值为null的时候,那么hashCode 值为0
(7) 如果是数组,那么需要为每个元素当做单独的域来处理。
C、最后,把每个域的散列码合并到对象的哈希码中。

public class Person {
    private String name;
    private int age;
  
    public Person() {
        super();
    }
  
    @Override
    public boolean equals(Object another) {
        if (this == another) {
            return true;
        }
        if (another instanceof Person) {
            Person anotherPerson = (Person) another;
            if (this.getName().equals(anotherPerson.getName()) && this.getAge() == anotherPerson.getAge()) {
                return true;
            } else {
                return false;
            }
        }
        return false;
    }
  
    @Override
    public int hashCode() {
        int hash = 17;
        hash = hash * 31 + getName().hashCode();
        hash = hash * 31 + getAge();
        return hash;
    }

相关文章

网友评论

      本文标题:Java基础-equals()和hashCode()

      本文链接:https://www.haomeiwen.com/subject/ktpluqtx.html