哈希表
哈希表是计算机存储数据的重要结构之一,其中在集合中HashSet和HashMap的底层存储结构都包含哈希表。
哈希值
又称哈希码值,是JDK根据地址或者属性值,算出来的int类型的整数
Object类中有一个可以根据对象地址获得哈希值得方法。
- public inthashCode();(这是根据地址值算出来的哈希值)
- 如果没有重写hashCode方法,那么是根据对象的地址值计算出的hashCode()值;那么同一个对象多次调用hashCode方法返回的哈希值是相同的,不同对象的哈希值是不同的。
- 如果重写了hashCode()方法,一般都是通过对象的属性值计算出哈希值,如果不同对象的属性值是一样的,那么计算出来的哈希值也是一样的。
JDK中的哈希表:
- JDK8之前,底层采用数组+链表实现
- JDK8以后,底层进行了优化,由数组+链表+红黑树实现
首先解释一下JDK1.8之前的版本:
我们在创建HashSet集合的时候:
- 会创建一个默认长度为16,默认加载因子为0.75的数组,数组名称叫做table
- 根据元素的哈希值和数组的长度计算出元素应存入的位置
- 判断当前位置是否为null,如果是null直接存入
- 下一个添加的元素继续根据上面的方法计算出应该存入的位置,如果为null直接存入,如果不为null会调用equals();方法比较两者的属性值,如果属性值相同则不会存入,如果属性值不同则新元素存入数组中,老元素挂在新元素下面形成一个链表:
- 当数组里面存了16*0.75=12个元素时,数组就会扩容为原来的两倍,以此类推。
JDK1.8版本之后的哈希表:
JDK1.8版本之后只在链表上做出了修改,当一个链表的长度大于8时会自动转换成一个红黑树:
HashMap在哈希表中的存储
- HashMap在哈希表中的存储是将整个entry对象看做是一个整体
- 只计算键的哈希值
- 如果计算的存储地址一样只调用键的equals();方法比较键的属性值。
迎风少年