ArrayList
- ArrayList
- 使用分析
- 优点
- 改查效率高
- 自动扩容机制1.5倍
- 缺点
- 线程不安全,安全的可以用copyOnwritArrayList, synchronizedList,vector
- 插入和删除操作效率低
- 底层时用Object[]数组实现,需要连续的内存空间
- 遍历的时候如果被修改会出现ConcurrentModificationException异常
- 时间复杂度
- 随机访问 Q(1)
- 插入和删除尾部 Q(1)
- 插入和删除指定非尾部位置 Q(n)
- 适用场景:单线程情况下最常用的List就是
- 优点
- 设计分析
- 设计目标
- 单线程下高效的改查的List
- 设计思路
- 解决问题的思路
- 基于new Object[]数组解决随机访问
- 通过自动扩容解决容量问题
- 解决问题的思路
- 实现原理
- 基于new Object[]数组解决随机访问,通过自动扩容解决容量问题
- 设计目标
- 源码分析
- 继承机制
- public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable{
}
- public class ArrayList<E> extends AbstractList<E>
- 容量
- 扩容方法
- 扩容时机:增加元素时判断容量是否有空余,没有空余才扩容
- 无参构造函数 数组长度为0
- 有参构造函数
- 参数小于10则数组长度为10
- 参数大于10则数组长度为参数大小
- 自动扩容1.5倍
- 单次扩容时,如果增加到1.5倍后还是小于期望的Size,则直接扩到Size长度
- 扩容之后容量都会变为原来的 1.5 倍左右(oldCapacity 为偶数就是 1.5 倍,不是偶数责小于 1.5 倍)! 奇偶不同,比如:10+10/2 = 15, 33+33/2=49。如果是奇数的话会丢掉小数.
- 扩容到1.5倍的原因
- 位运算效率考虑:位运算方式都是2的倍数,要么2倍,要么0.5倍
- 空间考虑:在1.5倍和2倍的情况下为了减少空间浪费选择1.5倍
- 当需要的大小大于Integer.MAX_VALUE - 8时,使用最大数组长度Integer.MAX_VALUE
- 扩容方法
- System.arraycopy()
- Arrays.copyOf()
- 不能自动缩容,只能手动缩容
- 手动改容量
- 减少内存消耗:手动将数组长度减到size大小 trimToSize()
- 减少重复扩容时间:手动将数组长度库容到目标大小 ensureCapacity(int minCapacity)
- 迭代器按照下标顺序
- 异常类型
- ConcurrentModificationException 遍历时修改异常
- IndexOutOfBoundsException 下标越界异常
- 当初始化长度为负数时 非法参数异常 IllegalArgumentException
- 快速失败机制fail- fast
- 在增加删除操作时modcount增加
- 在获取迭代器遍历时,迭代器保存了ArrayList当前modcoun值,在迭代器每次执行next时先比较保存的modcoun和ArrayList当前的modcoun不同时,抛出异常ConcurrentModificationException
- https://www.cnblogs.com/ldq2016/p/18751225
- 可以存储NULL
- https://javaguide.cn/java/collection/arraylist-source-code.html#arraylist-%E7%AE%80%E4%BB%8B
- 继承机制
- 使用分析
作者: 一点点征服
出处:http://www.cnblogs.com/ldq2016/
本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利