HashMap 在 Java 中是一个使用高频的数据结构,JDK1.8 以后 HashMap 进行了一次翻天覆地的改变,本文基于 JDK1.8 分析一下 HashMap
存储结构转换
在 JDK1.8 以前 HashMap 采用的是数组+链表
的结构,JDK1.8 以后又引入了红黑树的结构,会在链接和红黑树之间转换,结合源码分析一下 HashMap 对数组+链表
和数组+红黑树
的转换
首先看一下数据的存储结构
transient HashMap.Node<K, V>[] table;
HashMap 定义了一个 Node 的数组,Node 的定义
static class Node<K, V> implements Entry<K, V> {
final int hash;
final K key;
V value;
HashMap.Node<K, V> next;
// ....省略
}
Node 中包含了四个属性hash
、key
、value
、next
。
key
、value
是调用 HashMap 的put()
方法传进来的。hash
是判断 key 是否重复的关键next
用于构建链表
所以 HashMap 默认是一个数组+链表
的形式
链表
是否要转换成红黑树
,是在调用put()
方法添加数据时判断的,跟着源码分析链表
转换成红黑树
的过程
put()
方法调用的是putVal()
方法,
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) {
// ...省略
while (true) {
if ((e = ((HashMap.Node) p).next) == null) {
((HashMap.Node) p).next = this.newNode(hash, key, value,(HashMap.Node) null);
//转换成红黑树
if (binCount >= TREEIFY_THRESHOLD - 1) {
this.treeifyBin(tab, hash);
}
break;
}