版本:jdk1.8
键值对的方式存储
线程不安全
底层由数组+链表/红黑树实现
键值都可以为null 键不允许重复 值可以重复
在没有hash碰撞的情况下增删改查的时间复杂度为O(1)
链表和红黑树会相互转化
数组+链表/红黑树实现
HashMap相关的UML
我们先来看看HashMap重要属性
链表节点
红黑树节点
涉及多个重要参数的构造
tableSizeFor的作用是重新计算数组的长度大于等于cap的最小2的幂,threshold扩容的阈值,等到数组初始化的时候回再次赋值
static final int tableSizeFor(int cap) {
int n = cap - 1;
n |= n >>> 1;
n |= n >>> 2;
n |= n >>> 4;
n |= n >>> 8;
n |= n >>> 16;
return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
}
来看看HashMap重要的几个方法
hashMap.put
直接看关键部分
hashMap.get
直接看关键部分
hashMap.remove
直接看关键部分
几个重要操作介绍完了,我们再来看看HashMap中内部的几个重要方法
扰动函数hash
扩容操作resize
算出hash值对应的数组下标
(n - 1) & hash
这几个方法也需要注意,后面讲解的LinkedHashMap会根据自己的特性来对这几个方法执行相应的实现
// LinkedHashMap操作后的回调
void afterNodeAccess(Node<K,V> p) { }
void afterNodeInsertion(boolean evict) { }
void afterNodeRemoval(Node<K,V> p) { }
这里只是贴出了一些比较重要的方法,想要查看更完整的HashMap源码解析点击这里