一、预备
Hash(key)===》对key的值进行了hash计算,得到了一个int类型的值。
Key,value进行存储的话,使用的数据结构是什么?
1.ArrayList的底层是数组(查询快)
aa | bb | cc | dd |
2.LinkedList底层是链表(指向下一个,是一个双向列表)增删快,查询慢
上一个元素的引用地址 | 数据 | 下一个元素的引用地址 |
3.HashMap源码的数据结构,既想要查询效率快,也想要增删效率高怎么办?
HashMap的源码猜测,结合数组和链表的优势,应该是数组+链表的组合
数组下面挂链表优点:查询走数组快,增删走链表快
二、分析数组
4.那么HashMap源码中key,value的存储单元是什么?
java设计一个对象,这个对象存储key,value
那么这个对象应该有什么属性?
伪代码如下
//自己推理存储的对象单元应该是这样
class Node<K,V>{
//定义key
private K key;
//定义value
private V value;
//定义位置指向下一个节点
private Node<K,V> next;
}
源码中的对象为如下。
点进去Node看这个对象发现
这个对象和我们推测的伪代码对象有点相似(多了一个hash值)
5.数组该怎么表示?
(1) Node<K,V> [] 该对象的数组
6.数组的大小怎么表示?
初始化大小Defaultsize=....如下图
上限大小
Maximumsize=...
重点:大小的解决方案
初始化大小是16,当数组大小不够的时候,有扩容机制,源码中有
扩容机制:扩容必须要有一个依据,要定义一个标准。
当数组中的数据达到多少的时候进入扩容
比如数组的总长度Totalsize=16
数组目前大小是size
size>totalsize*(一个小于1的数)
那么它的扩容因子是0.75
代表着这个数组已经使用的大小到达数组的总长度的3/4的时候进行扩容
那么在源码中表示数组已经使用的大小用 size
三、分析链表
(1) 链表的长度是否应该有一个限制
应该有限制,如果链表太长的话,存放倒链表中的话,就会特别慢,所以链表达到一定大小的话,也会进行改变。
(2)怎么改变?
jdk1.8的时候,如果链表的长度大于某个值的时候,下面的结构就变为红黑树了。
下面就是源码中的阈(yu)值
三、key,value对象来了存在哪里?
那么存在哪个地方,因为key是唯一的,那么源码中的计算是用的key去计算,计算出这个Node到底放在哪里
(1)key.hashcode----->int类型的值.
(2) 根据key.hashcode去得到一个int值之后调用哈希函数
hash(key)---->得到理想的值