关于Map类的使用小结

目录

1. 常用Map类和区别

2. HashMap工作原理

2.1 Put()执行过程

2.2 扩容机制

3. ConcurrentHashMap

3.1 工作原理

3.2 JDK7分段锁的优缺点


1. 常用Map类和区别

Map类包含:HashMap、HashTable、LinkedHashMap、TreeMap。

1) 从功能上区分。

  • HashMap:在Map中插入,删除,定位元素。
  • TreeMap:可以按照自定义顺序或自然顺序遍历。
  • LinkedHashMap:要求输入顺序和输出顺序相同。

2) 内部数据结构。

  • HashMap:数组+链表/红黑树。
  • HashTable:数组+链表。
  • LinkedHashMap:双向链表。
  • TreeMap:红黑树。

3) 线程安全性。

  • HashMap:非线程安全。
  • HashTable:线程安全。
  • LinkedHashMap:非线程安全。
  • TreeMap:非线程安全。

2. HashMap工作原理

HashMap是基于哈希算法来确定元素的槽,当我们向集合中存入数据时,它会计算传入的Key的哈希值,并利用哈希值取余来确定槽的位置。

如果元素发生碰撞,也就是这个槽已经存在其他的元素了,则HashMap会通过链表将这些元素组织起来。如果碰撞进一步加剧,某个链表的长度达到了8,则HashMap会创建红黑树来代替这个链表,从而提高对这个槽中数据的查找的速度。

数组的默认初始容量为16,这个容量会以2的指数进行扩容,当数组中的元素达到一定比例的时候HashMap就会扩容,这个比例叫做负载因子,默认为0.75。

2.1 Put()执行过程

1) 判断数组,若发现数组为空,则进行首次扩容。

2) 判断头节点,若发现头节点为空,则新建链表节点,存入数组。

3) 判断头节点,若发现头节点非空,则将元素插入槽内。

  • 若元素的key与头节点一致,则直接覆盖头节点。
  • 若元素为树型节点,则将元素追加到树中。
  • 若元素为链表节点,则将元素追加到链表中。(追加后,需要判断链表长度以决定是否转为红黑树。比如,若链表长度达到8、数组容量未达到64,则扩容。若链表长度达到8、数组容量达到64,则转为红黑树)
  • 插入元素后,判断元素的个数,若发现超过阈值则再次扩容。

2.2 扩容机制

HashMap中添加数据时,有三个条件会触发它的扩容行为:

1) 如果数组为空,则进行首次扩容。

2) 将元素接入链表后,如果链表长度达到8,并且数组长度小于64,则扩容。

3) 添加后,如果数组中元素超过阈值,即比例超出限制(默认为0.75),则扩容。 并且每次扩容时都是将容量翻倍,即创建一个2倍大的新数组,然后再将旧数组中的数组迁移到新数组里。

3. ConcurrentHashMap

3.1 工作原理

JDK7 中的ConcurrentHashMap使用的是Segment和HashEntry。

JDK8 中的ConcurrentHashMap使用的是synchronized和CAS和HashEntry和红黑树。

ConcurrentHashMap和HashMap一样,使用了红黑树,而在ConcurrentHashMap中则是取消了Segment分段锁的数据结构,取而代之的是Node数组+链表+红黑树的结构,使用的 “读写锁”采用了CAS和Synchronized来保证线程的安全。

3.2 JDK7分段锁的优缺点

Segment继承了重入锁ReentrantLock,有了锁的功能,每个锁控制的是一段,当每个Segment越来越大时,锁的粒度就变得有些大了,具体分段数量由concurrencyLevel字段来控制。

1) 优点。

  • 在于保证在操作不同段 map 的时候可以并发执行,操作同段 map 的时候,进行锁的竞争和等待。这相对于直接对整个map同步synchronized是有优势的。

2) 缺点。同时这也是为什么在 JDK8 不在继续使用分段锁的原因。

  • 每个锁控制的是一段,当分段很多,并且加锁的分段不连续的时候,内存空间的浪费比较严重。

  • 操作map时竞争同一个分段锁的概率非常小时,分段锁反而会造成更新等操作的长时间等待。

  • 当某个段很大时,分段锁的性能会下降。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值