HashMap
特点 :
- 基于键的HashCode值唯一 , 键不可以重复
- 元素无序 , 按照键的哈希值存放
- key value 允许为空
- 非线程安全
原理 :
- jdk1.7 数组+链表
- jdk1.8 数组+链表+红黑树
// 构造方法
// 构造一个空 HashMap使用默认初始容量(16)和默认负载系数(0.75)。
public HashMap() {this.loadFactor = DEFAULT_LOAD_FACTOR;}
// 构造一个空 HashMap指定初始容量和默认负载系数(0.75)。
public HashMap(int initialCapacity) {this(initialCapacity, DEFAULT_LOAD_FACTOR);}
// 构造一个空 HashMap指定初始容量和装载因子。
public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0) throw new IllegalArgumentException("Illegal initial capacity: " +initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: " + loadFactor);
this.loadFactor = loadFactor;
this.threshold = tableSizeFor(initialCapacity);
}
/*
构造一个具有与指定映射相同映射的新HashMap。HashMap是用默认负载因子(0.75)和初始容量创建的,初始容量足以容纳指定映射中的映射。
参数:
m -其映射将被放置在这个映射中的映射
抛出:
如果指定的映射为空,则抛出NullPointerException
*/
public HashMap(Map<? extends K, ? extends V> m) {
this.loadFactor = DEFAULT_LOAD_FACTOR;
putMapEntries(m, false);
}
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // 默认初始容量(16)
static final int MAXIMUM_CAPACITY = 1 << 30; // 最大容量,如果较大的值由两个带参数的构造函数隐式指定时使用。一定是2的幂<= 1<<30。
static final float DEFAULT_LOAD_FACTOR = 0.75f; // 默认负载系数(0.75) 扩容2倍
static final int TREEIFY_THRESHOLD = 8; // 树化阈值 链表转成红黑树的阈值,在存储数据时,当链表长度大于8时,则将链表转换成红黑树
static final int UNTREEIFY_THRESHOLD = 6; // 树退化阈值 红黑树转为链表的阈值 当原有的红黑树内数量小于6时,则将红黑树转换成链表
/*
当哈希表中的容量大于该值时,才允许树形化链表 (即 将链表 转换成红黑树)
否则,若桶内元素太多时,则直接扩容,而不是树形化
为了避免进行扩容、树形化选择的冲突,这个值不能小于 4 * TREEIFY_THRESHOLD
*/
static final int MIN_TREEIFY_CAPACITY = 64; // 最小树形化阈值
整理好再更新…