面试知识点总结之集合框架TreeSet/TreeMap/ConcurrentHashMap/...
admin
2024-03-28 05:40:26

TreeSet:

首先 set是可以去重的,tree是实现排序的,总结:

TreeSet是一个包含有序的且没有重复元素的集合,通过TreeMap实现

它继承了AbstractSet抽象类,实现了NavigableSet,Cloneable,Serializable接口。
TreeSet是基于TreeMap实现的,TreeSet的元素支持2种排序方式:自然排序或者根据提供的Comparator进行排序。
 
TreeMap:
TreeMap可以比较元素大小,会对传入的key进行大小排序。自然顺序,自定义的比较器来进行排序;
数据结构:红黑树
TreeMap的基本操作 containsKey、get、put 和 remove 的时间复杂度是 log(n) 。 
 
ConcurrentHashMap:
 JDK1.7 和 JDK1.8 的实现方式不同
这里介绍JDK1.8
Node数组+链表+红黑树结构;在锁的实现上,抛弃了原有的 Segment 分段锁,采用CAS + synchronized实现更加细粒度的锁。
将锁的级别控制在了更细粒度的哈希桶数组元素级别,也就是说只需要锁住这个链表头节点(红黑树的根节点),就不会影响其他的哈希桶数组元素的读写,大大提高了并发度。
JDK1.8 中为什么使用内置锁 synchronized替换 可重入锁 ReentrantLock?
在 JDK1.6 中,对 synchronized 锁的实现引入了大量的优化,并且 synchronized 有多种锁状态,会从无锁 -> 偏向锁 -> 轻量级锁 -> 重量级锁一步步转换。
减少内存开销 。假设使用可重入锁来获得同步支持,那么每个节点都需要通过继承 AQS 来获得同步支持。但并不是每个节点都需要获得同步支持的,只有链表的头节点(红黑树的根节点)需要同步,这无疑带来了巨大内存浪费。
如何put

根据 key 计算出 hash 值;
判断是否需要进行初始化;
定位到 Node,拿到首节点 f,判断首节点 f:
如果为 null ,则通过 CAS 的方式尝试添加;
如果为 f.hash = MOVED = -1 ,说明其他线程在扩容,参与一起扩容;
如果都不满足 ,synchronized 锁住 f 节点,判断是链表还是红黑树,遍历插入;
4. 当在链表长度达到 8 的时候,数组扩容或者将链表转换为红黑树。

get

根据 key 计算出 hash 值,判断数组是否为空;
如果是首节点,就直接返回;
如果是红黑树结构,就从红黑树里面查询;
如果是链表结构,循环遍历判断。
get 方法不需要加锁。因为 Node 的元素 value 和指针 next 是用 volatile 修饰的,在多线程环境下线程A修改节点的 value 或者新增节点的时候是对线程B可见的。

ConcurrentHashMap 不支持 key 或者 value 为 null 的原因?

我们先来说value 为什么不能为 null。因为 ConcurrentHashMap 是用于多线程的 ,如果ConcurrentHashMap.get(key)得到了 null ,这就无法判断,是映射的value是 null ,还是没有找到对应的key而为 null ,就有了二义性。

而用于单线程状态的 HashMap 却可以用containsKey(key) 去判断到底是否包含了这个 null 。

相关内容

热门资讯

山水皆有情!丽江两山一江的千年... 去过丽江、走过虎跳峡的人,大概率都听过哈巴雪山和金沙江的传说。很多人站在峡谷之下,望着奔腾不息的金沙...
活力中国调研行丨“殷”你而来 ... 9月12日,游客在殷墟博物馆“甲骨文展厅”内参观。位于河南省安阳市的殷墟博物馆新馆是首个全景式展现商...
浦江之夜赴美好相逢,第37届上... 9月12日晚,黄浦江畔灯火璀璨,第37届上海旅游节大巡游在外滩中山东一路上演。不少观众早早便来到外滩...
美丽中国丨秋韵紫鹊界 梯田入画... 这是9月11日拍摄的紫鹊界梯田(无人机照片)。 金秋九月,湖南省娄底市新化县紫鹊界梯田稻谷渐次成熟。...
中国之巅奏响《共同的节日》,千... 千吨阻尼器,“迎世赛、游上海旅游节”。9月13日,由上海市文化和旅游局指导推出上海旅游·会客│巅峰之...