文章目录
HashMap是什么
HashMap的底层逻辑是数组+链表+红黑树(冲突严重的链表会被"树化",转为红黑树,以提高冲突严重的链表的查询效率)
如何解决哈希冲突
闭散列
开放地址法
也称为为线性探测法
- 一次探测法
缺点:会把冲突元素放到了一起.
当表的长度为质数,且装载因子不超过0.5的时候,新的表项一定能够插入,而且任何位置不会被探查两次,因此只要表中有一半的空位置,就不会存在表满的问题,在搜索时,可以不考虑表满的情况,但在插入时,一定要保证负载因子 < 0.5
超过就必须扩容.
缺点:空间利用率比较低.
二次探测法
开散列(哈希桶)
链地址法(开链法)
JDK8使用的是链表尾插法
数组 + 链表
成员变量
你了解重新调整HashMap的大小存在什么问题吗?
需要重新哈希原来的元素,添加到新的链表中
树化逻辑
当一个桶中链表元素个数>=8并且哈希表中所有元素个数加起来超过64,此时会将此桶中链表结构转为
红黑树结构(提高链表过长导致的查找太慢问题,从原来的O(n)优化为O(logn),减少哈希碰撞)
若只是链表个数大于8而哈希表元素不超过64,此时只是简单的resize而已,并不会树化。
无参构造
构造一个空的HashMap,使用默认的初始容量(16)和默认的负载因子(0.75)
有参构造
传入初始化容量,如果初始化容量是负数,抛出异常.
HashMap会将传入的参数做校验,返回距离传参最近的一个2n值。例如传入15,会初始化为16
put和get方法
final V putVal ( int hash, K key, V value,boolean onlyIfAbsent,
boolean evict){
Node<K, V>[] tab;
Node<K, V> p;
int n, i