转载自https://github.com/Snailclimb/JavaGuide (添加小部分笔记)感谢作者!
简介#
底层是数组队列,相当于动态数组,能动态增长,可以在添加大量元素前先使用ensureCapacity来增加ArrayList容量,减少递增式再分配的数量 源码:
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable{ }- Random Access,标志接口,表明这个接口的List集合支持快速随机访问,这里是指可通过元素序号快速访问
- 实现Cloneable接口,能被克隆
- 实现java.io.Serializable,支持序列化
ArrayList和Vector区别
- ArrayList和Vector都是List的实现类,Vector出现的比较早,底层都是Object[] 存储
- ArrayList线程不安全(适合频繁查找,线程不安全 )
- Vector 线程安全的
ArrayList与LinkedList区别
都是不同步的,即不保证线程安全
ArrayList底层为Object数组;LinkedList底层使用双向链表数据结构(1.6之前为循环链表,1.7取消了循环)
插入和删除是否受元素位置影响
ArrayList采用数组存储,所以插入和删除元素的时间复杂度受元素位置影响[ 默认增加到末尾,O(1) ; 在指定位置,则O(n) , 要往后移动]
LinkedList采用链表存储,所以对于add(E e)方法,还是O(1);如果是在指定位置插入和删除,则为O(n) 因为需要遍历将指针移动到指定位置
//LinkedList默认添加到最后 public boolean add(E e) { linkLast(e); return true; }LinkedList不支持高效随机元素访问,而ArrayList支持(通过get(int index))
内存空间占用 ArrayList的空间浪费主要体现在list列表的结尾会预留一定的容量空间,而LinkedList的空间花费在,每个元素都需要比ArrayList更多空间(要存放直接前驱和直接后继以及(当前)数据)
3. 扩容机制分析 ( JDK8 )#
ArrayList的构造函数
- 三种方式初始化,构造方法源码
- 空参,指定大小,指定集合 (如果集合类型非Object[].class,则使用Arrays.copyOf转为Object[].class)
- 以无参构造方式创建ArrayList时,实际上初始化赋值的是空数组;当真正操作时才分配容量,即添加第一个元素时扩容为10
/** * 默认初始容量大小 */ private static final int DEFAULT_CAPACITY = 10; private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; /** *默认构造函数,使用初始容量10构造一个空列表(无参数构造) */ public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } /** * 带初始容量参数的构造函数。(用户自己指定容量) */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) {//初始容量大于0 //创建initialCapacity大小的数组 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) {//初始容量等于0 //创建空数组 this.elementData = EMPTY_ELEMENTDATA; } else {//初始容量小于0,抛出异常 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } /** *构造包含指定collection元素的列表,这些元素利用该集合的迭代器按顺序返回 *如果指定的集合为null,throws NullPointerException。 */ public ArrayList(Collection<? extends E> c) { elementData = c.toArray(); if ((size = elementData.length) != 0) { // c.toArray might (incorrectly) not return Object[] (see 6260652) if (elementData.getClass() != Object[].class) elementData = Arrays.copyOf(elementData, size, Object[].class); } else { // replace with empty array. this.elementData = EMPTY_ELEMENTDATA; } }以无参构造参数函数为例 先看下面的 add()方法扩容



而对于enum类型,


