HashMap
HashMap
-
HashMap底层是哈希表数据结构
-
哈希表是一个怎样的数据结构?
哈希表是数组和单向链表的组合体
数组: 查询效率高,随机增删效率低
单向链表: 查询效率低,随机增删效率高
哈希表是将以上两种数据结构融合,充分发挥各自的优点
-
HashMap底层源代码
public class HashMap<K,V>{ //HashMap 底层实际上就是一个一维数组 transient Node<K,V>[] table; //静态内部类HashMap.Node static class Node<K,V> implements Map.Entry<K,V> { final int hash;// 哈希值(是key的hashcode()方法的执行结果,hash值通过hash算法,可以得到数组下标 ) final K key; V value; Node<K,V> next; } } //哈希表:一维数组,这个一维数组里每个元素里存的是一个单向链表 -
V put(K key, V value)的实现原理
第一步: 先将k 和 v 封装到Node对象里
第二步: 底层会调用 k 的 hashCode() 方法, 获得hash值, 然后通过哈希算法, 将hash值转成数组的下标, 下标位置上如果为null, 就把Node添加到这个位置上; 如果不为null, 就会拿着k 和这个下标下的链表里的每一个k进行equals ,如果都返回null,则将Node加在这个链表的末节点, 如果其中有一个返回true,则会覆盖,这个 k 上的 v
-
V get(Object key)的实现原理
先调用k的hashCode() 方法, 获得hash值, 然后通过哈希算法, 将hash值转成数组的下标, 下标位置上如果为null,则返回null; 如果不为null, 就会拿着k 和这个下标下的链表里的每一个k进行equals ,如果都返回null,则返回null; 如果其中有一个返回true,则返回这个k 上的 v
-
HashMap集合key部分的特点:
无序,不可重复
为什么无序? 因为不知道挂到哪个链表上
怎么保证不可重复:? equals方法保证HashMap的key不可重复,如果key重复,value会被覆盖
-
注意: 同一个单向链表上的所有节点的hash值相同
-
哈希表使用不当时无法发挥性能
假设将所有的hashCode() 返回值固定为某个值,那么会导致哈希表底层变成了纯单向链表. 这种情况我们成为 : 散列分布不均匀
假设所有的hashCode()的返回值都不一样,那么会导致哈希表底层变成了一维数组,这种情况也是 散列分布不均匀
-
重点 : 放在HashMap 集合key部分的元素,需要同时重写equals和hashCode 方法
没重写equals方法,会导致可以存入相同内容的key
没重写hashCode 方法,会导致hash值都不一样,那么会导致哈希表底层变成了一维数组
-
HashMap集合的默认初始化容量是16,默认加载因子是0.75
默认加载因子 : 当HashMap容量达到75%时会进行扩容,扩容后容量时原容量的2倍
重点 : HashMap的初始化容量必须是2的倍数,这也是官方推荐的
这是为了达到散列分布均匀, 使HashMap的存储效率提高
-
在jdk8以后,如果哈希表里的单向链表里的元素超过8个,那么这个单向链表的数据结构会转换成红黑树数据结构; 当红黑树节点的数少于6个时,那么红黑树会转换成单向链表
-
hash值相同的节点一定在同一链表下,hash值不同的节点可能在同一链表下,这现象叫"哈希碰撞"
-
HashMap的key值允许为null,但最多只能有一个
-
HashTable的key和value均不能为null
浙公网安备 33010602011771号