1. HashMap总览
1.1 hashmap底层储存结构图解
底层结构其实就是数组+链表+红黑树
1.2 HashMap类定义
先来看看HashMap的定义:
1 | public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable {} |
从中我们可以了解到:
HashMap<K,V>
:HashMap
是以key-value
形式存储数据的。extends AbstractMap<K,V>
:继承了AbstractMap
,大大减少了实现Map接口时需要的工作量。implements Map<K,V>
:实现了Map
,提供了所有可选的Map
操作。implements Cloneable
:表明其可以调用clone()
方法来返回实例的field-for-field
拷贝。implements Serializable
:表明该类是可以序列化的。
1.3 put()数据原理分析图解
1.4 一些名词
- hashmap的底层数据结构名为table的数组,是一个Node数组
- table数组中的每个元素是一个Node元素(但是这个Node元素可能指向下一个Node元素从而形成链表),table数组的每个位置称为桶,比如talbe[0] 称为一个桶,也可以称为一个bin
2. 源码
2.1 核心属性分析
静态常量
1 | /** |
成员变量
1 | /** |
2.2 构造方法分析
仅仅看最长参数的构造方法就行了,其它三个都是调用了此构造方法:
1 | public HashMap(int initialCapacity, float loadFactor) { |
2.3 put方法分析
1 | /** |
2.4 resize方法分析
当在table长度位16中的元素移到table长度位32的table中的时候;我们可以知道,原来在15这个槽位的元素的hash()值的后四位一定是1111(因为跟1111即table长度-1 进行与运算得到了1111)。所以所以当table长度变为32的时候,原来在15这个槽位的元素要么还在15这个槽位,要么在31这个操作(因为原来15这个槽位的元素后五位一定是11111或者01111,跟 11111即table新长度-1 进行与运算一定得到 01111或者11111)
1 | /** |
2.5 get方法分析
1 | public V get(Object key) { |
2.6 remove方法分析
1 | public V remove(Object key) { |
2.7 replace方法分析
1 |
|
2.8 其它常用方法
isEmpty()
1 | /** |
putMapEntries()
1 | final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) { |
putAll()
1 | /** |
clear()
1 | /** |
containsValue( Object value)
1 | /** |