关于ArrayList的学习总结

136 阅读2分钟

摘要

对ArrayList的优势进行了简要的说明,对ArrayList的初始化过程和插入过程进行了介绍,最后写了一些关于ArrayList使用时需要注意的地方。希望可以得到大家的批评指正!

ArrayList的优势

因为ArrayList的底层是由数组实现,因此支持RandomAccess随机访问,但增加或者删除时会带来复制的成本,所以比较适合读多写少的场景。

ArrayList初始化过程

初始化ArrayList时,如果不指定数组大小,则不会分配空间,而是在插入第一条数据到ArrayList中时再进行空间的分配,默认空间为10;如果指定大小,则在初始化的过程中就会给ArrayList分配相应大小的空间。

ArrayList的插入过程

  1. 首先到用ensureCapacityInterval方法来确保ArrayList中还存在剩余的空间
  2. 如果没有剩余的空间,就会调用grow方法进行扩容(扩容到原来的1.5倍)
  3. 最后进行数据的插入(默认插入到数组最后一个元素之后)

一点小Tip

由于添加元素的时候会不断地带来复制的成本,所以常常给ArrayList一个初始的大小,避免不断的复制(空间换时间)。同时ArrayList像一个胃口越来越大的孩子,当你给ArrayList添加了很多元素后,它的胃口也就被涨大了,此后就算remove掉了很多元素,底层的Object数组的容量也并不会减少,如果需要释放掉Object数组占用的空间,需要手动的调用trimToSize方法。

关于LinkedList

LinkedList是一种带头尾节点的双向链表结构,适合写多读少的场景。很明显,LinkedList的add、remove效率要优于ArrayList,因为ArrayList要移动元素,LinkedList的get、set操作效率要比ArrayList低,因为LinkedList要遍历节点找到指定节点。

关于Vector

与ArrayList相比,Vector是线程安全的,当需要扩容时,Vector会将容量增加为原来的两倍。

关于CopyOnWriteArrayList

如果要获取线程安全的ArrayList,通常不会选择Vector,因为Vector使用的是同步方法来保证线程安全,效率会非常的低。所有常采用JUC包下的CopyOnWriteArrayList,CopyOnWriteArrayList在写操作的同时允许读操作,大大提高了读操作的性能,因此很适合读多写少的应用场景。同时因为其写操作是在复制是数组上进行的,所以通常会带来额外一倍的线程开销,同时还会存在数据不一致的情况,所以不是很适合要求实时性的场景。