ArrayList源码&扩容机制分析

介绍

ArrayList 的底层是数组队列,相当于动态数组。Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量,这可以减少递增式再分配的数量。ArrayList继承于 AbstractList ,实现了 List, RandomAccess, Cloneable, java.io.Serializable 这些接口。
RandomAccess 是一个标志接口,表明实现这个这个接口的 List 集合是支持快速随机访问的。
Cloneable 接口 ,即覆盖了函数clone(),能被克隆
Serializable接口,这意味着支持序列化,能通过序列化去传输。
ArrayList里面的数组初始容量(capacity)默认为10,超过长度自动扩容,扩容为1.5倍。以无参数构造方法创建 ArrayList 时,实际上初始化赋值的是一个空数组。当真正对数组进行添加元素操作时,才真正分配容量。即向数组中添加第一个元素时,数组容量扩为 10。

java 中的 length说明
1、针对数组说,代表数组的长度则 length 属性.
2、针对字符串说的,查看字符串的长度则用到length() 方法.
3、针对泛型集合说的,查看这个泛型有多少个元素用size() 方法

​ 数组的删除都是把要删除的元素后面的元素向左迁移,重新创建一个新的数组,copy过去数组过去,copy的时候数据的原size-1。之后把原来数据最后一个元素置为null,原来的数组没有了引用,就会被GC回收


1.1. Arraylist 和 Vector 的区别?

​ ArrayList 是 List 的主要实现类,底层使用 Object[ ]存储,适用于频繁的查找工作,线程不安全 ;
​ Vector 是 List 的古老实现类,底层使用 Object[ ]存储,新增方法使用synchronized 进行修饰,是线程安全的。

1.2. Arraylist 与 LinkedList 区别?

是否保证线程安全:

​ ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;

底层数据结构:

Arraylist 底层使用的是 Object 数组;LinkedList 底层使用的是双向链表数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环)

插入和删除是否受元素位置的影响:

​ ① ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候,ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。
​ ② LinkedList 采用链表存储,所以对于add(E e)方法的插入,删除元素时间复杂度不受元素位置的影响,近似 O(1),如果是要在指定位置i插入和删除元素的话((add(int index, E element))时间复杂度近似为o(n))因为需要先移动到指定位置再插入。

是否支持快速随机访问:

LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。

内存空间占用:

​ ArrayList 的空间浪费主要体现在在 list 列表的结尾会预留一定的容量空间.

​ LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要存放直接后继和直接前驱以及数据)。

1.3 System.arraycopy() 和 Arrays.copyOf()方法

​ 数组扩容操作和添加方法中用到这两个.

Arrays.copyOf()方法主要是为了给原有数组扩容,copyOf()内部实际调用了 System.arraycopy() 方法。arraycopy() 需要目标数组,将原数组拷贝到你自己定义的数组里或者原数组,而且可以选择拷贝的起点和长度以及放入新数组中的位置 copyOf() 是系统自动在内部新建一个数组,并返回该数组

1.4 ensureCapacity方法

​ ArrayList add 大量元素之前用 ensureCapacity 方法,以减少增量重新分配的次数.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值