文章目录
HashMap的put工作原理
HashMap底层是哈希表,哈希表就是一个数组,数组的元素是链表,它结合了数组与链表的优点
put的执行流程
put时的几种情况:
- hashmap.put(“lisi”,22); 添加键值对时
根据键的哈希码,经过哈希函数计算得出hash值
根据hash值计算数组下标 i=4
访问数组元素table[i],如果该元素为null,就创建一个节点保存到table[i]中 - hashmap.put(“chen”,20); 添加键值对时
根据键的哈希码,经过哈希函数计算得出hash值
根据hash值计算数组下标 i=0
访问数组元素table[i],如果该元素为null,就创建一个节点保存到table[i]中 - hashmap.put(“wu”,36); 添加键值对时
根据键的哈希码,经过哈希函数计算得出hash值
根据hash值计算数组下标 i=0
访问数组元素table[i],如果该元素不为null,就遍历table[i]链表中所有的节点,如果所有节点的key与当前key不同,就创建一个节插入到链表的尾部 - hashmap.put(“chen”,22); 添加键值对时
根据键的哈希码,经过哈希函数计算得出hash值
根据hash值计算数组下标 i=0
访问数组元素table[i],如果该元素不为null,就遍历table[i]链表中所有的节点,如果所有节点的key与当前键equals()相等,就使用新的value值替换节点中的值
总结:
- HashMap底层是哈希表,哈希表就是数组,数组的元素是链表
- put添加键值对时执行以下过程:
- 先根据键的哈希码,经过hash函数计算hash值
- 根据hash值计算数组的下标 i
- 访问table[i] 元素,如果元素为null,就创建节点保存到元素中;如果不为null,就遍历table[i] 链表中的所有节点,如果有某个节点的key与当前的键Equals相等,就用新的value值替换节点中的值;如果所有节点都不匹配,就创建一个新的节点插入到链表尾部
HashMap的get工作原理(参照put理解)
- 根据键的哈希码,经过hash函数计算hash值
- 根据hash值计算数组下标i
- 访问table[i]元素,如果该元素为null,返回null; 如果该元素不为null, 遍历table[i]链表中的每个结点, 如果有某个结点的key与当前的键Equals相等, 就把该结点的value值返回; 如果所有结点的key与当前的键都不一样,返回 null
HashMap如何解决哈希冲突的?
采用链表法
哈希冲突,也叫哈希碰撞, 简单点说就是不同的键都想在存储在数组的同一个位置上
了解内容:
- 如果两个键equals相等,根据哈希约定,这两个键的哈希码应该一样, 哈希码一样经过hash函数计算的hash值也应该相等, hash值相等计算的数组下标也应该一样 .
- 两个equals不相等的键, 它们的哈希码可能一样;
两个键的哈希码不一样, 计算得出的hash值可能一样
两个不相等的hash值,计算得出的数组下标可能一样
在JDK8中对HashMap做了哪些改进 ?
- 新增的结点插入到链表的尾部.(在JDK7之前新增的结点是插入到链表的头部的.)
- 当单向链表中结点的数量超过8个时,系统会把单向链表转换为红黑树结构(红黑树是一种自平衡二叉树)
HashTable与HashMap的区别
- 底层都是哈希表, HashTable是线程安全的, HashMap不是线程安全的
- 初始化容量: HashTable为11, HashMap为16
- 加载因子: 0.75 , 当键值对的数量 > 容量*加载因子时,扩容
- 扩容: HashTable按2倍+1, HashMap按2倍大小扩容
- 在使用时HashTable的键与值都不能为null, 而HashMap的键与值都可以为null
- 在创建时可以指定初始化容量, HashMap会把初始化容量自动调整为2的幂次方, 为了快速计算数组的下标; HashTable不调整