本篇所查看源码为jdk1.8源码
一、数组和散列表对比
数组数通过索引值直接找到value值
数组
散列表不同在于,可以通过自定义的key值,找到对应的value值
散列表和数组的区别在于散列表是有映射关系存在的
散列表
二、查看HashMap的继承关系
看一下HashMap的类,它会继承AbstractMap 实现Map接口,Cloneable,Serializable接口
抽象类AbstractMap会实现Map接口
这样我们就明白了,其实HashMap就是实现了Map接口,也就是实现了散列表的基础接口而已
现在看一下map接口,这个接口涉及到散列表的一些基本操作,比如散列表数据长度,插入数据,删除数据等
但是有一点不太一样的地方,就是这个接口里面包含了一个内部接口
在hashMap中,我们发现存在一个静态内部类是实现了这个接口
这个node类超级简单,四个数据,分别是哈希、key值、value值,以及node域,因为key值会生成hash值,但是key值也是需要存储下来的,所有一同存到了Node对象里,hashMap就是用这个类存放节点数据的。
三、构造方法
1、无参构造函数,容量16,负载因子默认0.75
2、带int参数构造函数,容量为传进来的值,负载因子默认0.75,会调用3方法
3、带int参数构造函数,容量为传进来的值,负载因子为传进来的值
4、带Map实例构造函数
合并Map实例数据到当前的hashMap容器中
putMapEntries函数
tableSizeFor是为了返回大于输入参数且最近的2的整数次幂的数,这个当然是为了容器更好的性能,具体需要好好研究一下。
tableSizeFor函数
四、插入数据
插入数据分成了两张图,填上了对应的注释,hashmap是懒加载的,所以这首次添加数据就会涉及到扩容操作,扩容方法为resize()
putVal 图一
putVal 图二
resize()扩容方法
分成了三张图
自动扩容 图一
自动扩容 图二
自动扩容 图三
五、删除数据
删除数据和新增数据代码很像,这个会涉及到红黑树的数量过少时转链表的操作
remove方法
删除方法 图一
删除方法 图二
六、清空容器
清空方法很简单,将哈希桶数据置为null,真实数据由gc程序进行回收