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版本的区别

关于Java的HashMap
关于Java的HashMap

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幂指数

相关文章: