当前位置:   article > 正文

java集合与底层实现(中)_java 集合存底层储方式

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
  • 2
  • 3
  • 4
  • 5
  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
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/971051
推荐阅读
相关标签
  

闽ICP备14008679号