【面试必背】集合篇

集合

ArrayList

底层是动态数组,初始数组长度为0,add后默认为10,当需要增加的数组长度大于自身,会触发扩容,生成一个大于自身1.5倍的空数组,将原数组拷贝到新数组
根据下标查询,所以查询快,增删慢,修改需要移动其他数组位置

Vector

大部分方法被synchronized关键字修饰,线程安全的数组,扩容为2倍

LinkedList

底层是双向链表,头插LinkedFirst,尾插LinkedLast
链表是线性的数据存储,需要移动指针从前往后查找,所以查询慢;增删快,只用更改前后元素指针的指向,因为链表存储元素的同时,每个元素维护着前后指向的指针,但更占内存

HashMap

1.7是数组+单链表,1.8是数组+单链表+红黑树,链表和红黑树的转换,单链表长度大于等于8,并且hash桶长度大于等于64时,会将链表转换为红黑树,红黑树节点数据小于等于6时会转换为单链表
HashMap是非线程安全,多线程情况下1.7会产生循环链表,1.7是头插,t1将k2插入k1前时,t2发生resize,t2链表为k1-k2,t1链表为k2-k1;1.8改成尾插

扩容机制

hash桶默认是16,负载因子默认是0.75,阈值为16*0.75=12,hash桶占用容量超过12时会触发扩容,扩容成之前hash桶的2倍,2的N次幂,将之前的元素再进行一次hash运算,填充到新的hash桶中,按链表或红黑树的方式排列

HashMap的数组长度一定是2的次幂:

减少链表上元素的移动代价。因为按二次幂进行扩展,链表上元素的位置要么是在桶的原位置,要么在桶原位置再移动2次幂的位置

Hash冲突

  1. 开放地址法
    关键字key出现冲突时,寻找下一个地址将key存起来
  2. 拉链法
    将所有关键字相同的存在链表中
  3. rehash
    再用另外一个哈希函数算出哈希值,直到算出不同值

ConcurrentHashMap

1.7底层是分段数组,为了保证线程安全有个Segment锁,每次只加一段锁保证并发度
1.8改成数组+链表+红黑树,会逐渐放弃这种分片锁机制,使用synchronized和CAS来操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值