HashMap相关知识
基本概念
- 数据结构:数组+链表(拉链法),链表长度超过8,链表转为红黑树(保证平衡)
- 工作原理:数组中每个元素都是链表,由Node内部类实现
- 存储:调用hash(K)计算K的hash,结合数组长度,计算数组下标;扩容时增加一倍;hash值已存在时会发生碰撞——比对两者equals,true则更新键值对,false则插入链表尾部或红黑树中(注:jdk1.7使用头插;jdk1.8使用尾插)
- 获取:使用hash(K)计算数组下标位置,遍历链表使用equals()方法查找值
- hashCode()定位;equals()定性,判断二者是否相等
- hashCode相同时:不一定就相等,因为HashMap使用链表存储对象,Node会存储到链表中
- hash的实现:通过hashCode()的高16位异或地16位实现,从速度、功效、质量来考虑,使用异或是为了尽可能减少碰撞
- HashMap的table、loadFactor:table即数组大小,由capacity就决定,默认16;loadFactor:装载因子,用于判断table是否需要动态扩容
- 扩容过程:创建容量为原来两倍的新数组,计算旧数组中节点的存储位置,——原下标位置或原下标+旧数组大小
HashMap中关于红黑树的应用
- 红黑树:节点非黑即红;根节点为黑色;节点红色,则子节点必须为黑色;叶子节点都是黑色;根节点到叶节点或空子节点的每条路径,包含相同数目的黑色节点。
jdk1.8中HashMap的新特性
- 链表长度超过8,转为红黑树
- 发生碰撞,使用尾插
- Entry被Node替换
HashMap、LinkHashMap和TreeMap的区别
- LinkHashMap:记录了插入顺序,遍历比HashMap慢
- TreeMap:实现SortMap接口,能将记录按键排序
HahsMap和HashTable的区别
- HashMap线程不安全;HasjTable线程安全
- HashMap只允许一条记录的键为null,HashTable不允许
- HashTable扩容为两倍+1
- HashMap重新计算对象的hash值,HashTable直接使用对象的hashCode
HashMap在1.7和1.8版本的区别


HashMap、HashTable和ConcurrentHashMap的区别
- HashTable使用synchronize关键字加锁;jdk1.7中ConcurrentHashMap采用分段锁,jdk1.8中直接使用CAS(无锁算法)+synchronize实现
- ConcurrentHashMap比HashTable效率高:HashTable使用一把锁锁住整个链表结构,ConcurrentHashMap降低了锁粒度——1.7使用ReentrantLock(可重入)+Segment+HashEntry,1.8中使用CAS+synchronize+Node+红黑树
- 为何使用synchronize代替ReentrantLock:粒度降低;优化空间更大;大量数据操作下,基于API的ReentrantLock开销更多内存
ConcurrentHashMap相关
- 常量:private transient volatile intsizeCtl
- 并发度:默认为16,若设置了,则实际并发度为该值的最小2幂指数
相关文章: