本文共 3033 字,大约阅读时间需要 10 分钟。
1.概念解析: ArrayList底层就是个数组,不过他封装了一系列对数组的操作,并且实现了自动扩容
2.首先我们来看下类中有哪些属性
/** * 默认的初始化容量大小为10 */private static final int DEFAULT_CAPACITY = 10;/** * 用于共享空实例的共享空实例数组 */private static final Object[] EMPTY_ELEMENTDATA = {};/** * * 用来设定默认数组大小的共享空实例,用来确定第一次add时候,扩容多少 * */private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};/** * * 用于存储底层元素的数组结构 * * */transient Object[] elementData; // non-private to simplify nested class access/** * 数组中元素节点的数量 * */private int size;/** * * 最大数组大小 * * */private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
创建一个ArrayList对象方式
/** * 默认构造函数赋值DEFAULTCAPACITY_EMPTY_ELEMENTDATA. */public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
/** *自定义默认数组大小 */public ArrayList(int initialCapacity) { if (initialCapacity > 0) { //大于0直接new一个 this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { //等于0直接赋值EMPTY_ELEMENTDATA this.elementData = EMPTY_ELEMENTDATA; } else { //其他抛出参数异常 throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); }}
public ArrayList(Collection 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流程
public boolean add(E e) { //数量加1,并判断是否扩容 ensureCapacityInternal(size + 1); // Increments modCount!! //size++并赋值到最后一个元素下标,这里不会数组越界 elementData[size++] = e; return true;}
private void ensureCapacityInternal(int minCapacity) { //这里判断elementData对象是不是通过默认构造函数赋值的是则设置默认大小10或者+1 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { //当前数组的最小容量 minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); } //得到当前数组的最小容量 ensureExplicitCapacity(minCapacity);}
private void ensureExplicitCapacity(int minCapacity) { //修改次数++ modCount++; // 判断当前数组是否需要扩容 if (minCapacity - elementData.length > 0) //进行扩容 grow(minCapacity);}
private void grow(int minCapacity) { // 得到扩容前的旧容量 int oldCapacity = elementData.length; // 新容量增大1.5倍 int newCapacity = oldCapacity + (oldCapacity >> 1); //如果新容量扩大1.5倍还不够则直接赋值minCapacity addAll的情况 if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) //设置最大值 newCapacity = hugeCapacity(minCapacity); // 进行扩容: elementData = Arrays.copyOf(elementData, newCapacity);}
get
public E get(int index) { //get检测索引的范围 rangeCheck(index); //直接返回 return elementData(index);}
面试会问的问题:
1.ArrayList是什么?可以用来干嘛? ArrayList是一个动态数组结构,底层是数组支持动态扩容,可以用来存储数据2.ArrayList get和add时间复杂度? O(1)和O(N)3.ArrayList线程安全吗? 不安全,查询和更新没有加锁4.默认的初始化大小和扩容倍数系数 10和1.5
转载地址:http://imkji.baihongyu.com/