java集合与底层实现(中)

集合 List

特点:有序(存储顺序和取出顺序一致),可重复
ArrayLIst 数据结构是数组,线程不安全
LinkedList 数据结构是链表,线程不安全(双向链表方便实现往前遍历)
Vector 数据结构是数组,线程安全
copyOnWriteList 并发容器,线程安全(COW设计模式)

ArrayList解析
  • ArrayList底层为一个数组,内部有扩容的概念,初始容量为10,每次扩容增加原先容量的一半(1.5倍)实现了”动态“增长
  • ArrayList是基于动态数组实现的,在增删的时候,需要数组的拷贝复制
  • 删除元素时不会减少容量,若希望减少则调用trimToSize()
  • 它不是线程安全的,能存放null
  1. Add(E e)方法
    首先检查一下数组的容量是否足够,足够则直接添加,不够扩容,扩容到原来的1.5倍,第一次扩容后,如果容量还是小于minCapacity,就将容量扩容为minCapacity
  2. Add(int index,E e)
    检查角标是否越界,空间检查,如果有需要进行扩容,调用arraycopy()来进行插入(在高性能的jvm中,会对这种intrinsic method进行特殊优化处理,达到高效执行数组拷贝)
  3. get(int index)以及set(int index,E e)
    检查角标,返回元素/替代元素(会返回旧值)
  4. remove(int index)
    检查角标,计算出需要移动的个数,并移动、删除元素,elementData[—size] = null; 设置为null,让GC回收
Vector
  • Vector底层也是数组,它是线程安全
  • 如果想要ArrayList实现同步,可以使用Collections的方法:List list = Collections.synchronizedList(new ArrayList(…));,就可以实现同步
  • Vector扩容原来的1倍,arrayList扩容原来的0.5倍
LinkedLIst
  • 底层是双向链表
  • linkedList实现了deque接口,我们可以操作linkedList像操作队列和栈一样
  1. add(E e)方法
    往链表最后添加元素
final node temp = last;
final newNode = new Node();
last = newNode;
l.next = newNode;
Size++;
  1. remove(Object o)
    双向链表删除数据
  2. get(int index) 、set(int index,E e)
    通过传入的下标与size对比,下标小于长度的一半,就从头遍历,否则从尾遍历
copyOnWriteList

1.Hashtable、Vector加锁的粒度大(直接在方法声明处使用synchronized)
2.ConcurrentHashMap、CopyOnWriteArrayList加锁粒度小(用各种的方式来实现线程安 全,比如我们知道的ConcurrentHashMap用了cas锁、volatile等方式来实现线程安全…)
3.JUC下的线程安全容器在遍历的时候不会抛出ConcurrentModificationException异常

  • CopyOnWriteArrayList是线程安全容器(相对于ArrayList),底层通过复制数组的方式来实现。
  • CopyOnWriteArrayList在遍历的使用不会抛出ConcurrentModificationException异常,并且遍历的时候就不用额外加锁
  • 元素可以为null
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值