Java基础知识(二):hashCode VS equals

2021-09-06  本文已影响0人  codeMover

2. hashCode VS equals

2.1 hashCode介绍

hashCode()的作用是获取哈希码,也成为散列码;它实际上返回一个int整数。这个哈希码的作用是确定该对象在哈希表的索引位置。hashCode()定义在JDK的Object中,这就意味java中任何类都包含hashCode()函数。

2.2 equals介绍

equals的作用也是判断两个对象是否相等,如果对象重写了equals()方法,比较两个对象的内容是否相等;如果没有重写,比较两个对象的地址是否相等,等价于“==”。同样的,equals()定义在JDK的Object中,这就意味着java中的任何类都包含equals()函数。

2.3 hashCode()和equals()关系

2.3.1 不会创建“类对应的散列表”

不会创建“类对应的散列表”是指我们不会再HashSet、HashTable、HashMap等本质是散列表的数据结构中用到该类。例如不会创建该类的HashSet集合。

这种情况下,该类的hashCode()和equals()没有关系。

equals()用来比较该类的两个对象是否相等,

hashCode()在此场景没有任何作用。

2.3.2 会创建“类对应的散列表”

会创建“类对应的散列表”是指我们会再HashSet、HashTable、HashMap等本质是散列表的数据结构中用到该类。例如会创建该类的HashSet集合。

在这种情况下,该类的hashCode()和equals()是有关系的:

如果类使用散列表的集合对象中,要判断两个对象是否相同,除了要覆盖equals()之外,也要覆盖hashCode()否则equals()无效。

2.4 复写hashCode的诀窍

一个好的hashCode的方法目标:为不相等的对象产生不相等的散列码,同样的,相等的对象必须拥有相等的散列码。

31*result + c:乘法使hash值依赖于域的顺序,如果没有乘法那么所有顺序不同的字符串String对象都会有一样的hash值。31是一个奇素数,如果是偶数,并且乘法溢出的话,信息会丢失,31有个很好的特性就是31*i ==(i<<5)-i,即2的5次方减1,虚拟机会优化乘法作为移位操作的。
    【例如Objects里的方法,计算对象hash值】
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }
    【例如String里的方法,计算单个属性hash值】
    public static int hashCode(Object a[]) {
        if (a == null)
            return 0;

        int result = 1;

        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

        return result;
    }
上一篇下一篇

猜你喜欢

热点阅读