【java基础】集合
- Collection关系图
| 集合 | 是否有序 | 唯一性 | 线程安全 | 底层结构 | 查询增删特点 |
|---|---|---|---|---|---|
| ArrayList | 有序 | 可重复 | 不安全 | 数组 | 查询快,增删慢 |
| Vector | 有序 | 可重复 | 安全 | 数组 | 查询快,增删慢 |
| LinkedList | 有序 | 可重复 | 不安全 | 链表 | 查询慢,增删快 |
| HashSet | 无序 | 唯一 | 不安全 | 哈希表 | |
| LinkedHashSet | FIFO插入有序 | 唯一 | 不安全 | 链表和哈希表 | |
| TreeSet | 有序 | 唯一 | 不安全 | 红黑树 |
- Map关系图
| 集合 | 是否有序 | 允许null值 | 线程安全 | 底层结构 | 查询增删特点 |
|---|---|---|---|---|---|
| HashMap | 无序 | 允许 | 不安全 | ||
| HashTable | 无序 | 不允许 | 安全 | ||
| TreeMap | 有序 | ||||
| LinkedHashMap | FIFO即有序 | 允许 | 不安全 |
-
集合相关面试题
CurrentHashMap源码
ConcurrentHashMap的数据结构(数组+链表+红黑树),桶中的结构可能是链表,也可能是红黑树,红黑树是为了提高查找效率。
put函数底层调用了putVal进行数据的插入,对于putVal函数的流程大体如下:
① 判断存储的key、value是否为空,若为空,则抛出异常,否则,进入步骤②
② 计算key的hash值,随后进入无限循环,该无限循环可以确保成功插入数据,若table表为空或者长度为0,则初始化table表,否则,进入步骤③
③ 根据key的hash值取出table表中的结点元素,若取出的结点为空(该桶为空),则使用CAS将key、value、hash值生成的结点放入桶中。否则,进入步骤④
④ 若该结点的的hash值为MOVED,则对该桶中的结点进行转移,否则,进入步骤⑤
⑤ 对桶中的第一个结点(即table表中的结点)进行加锁,对该桶进行遍历,桶中的结点的hash值与key值与给定的hash值和key值相等,则根据标识选择是否进行更新操作(用给定的value值替换该结点的value值),若遍历完桶仍没有找到hash值与key值和指定的hash值与key值相等的结点,则直接新生一个结点并赋值为之前最后一个结点的下一个结点。进入步骤⑥
⑥ 若binCount值达到红黑树转化的阈值,则将桶中的结构转化为红黑树存储,最后,增加binCount的值。