arraylist源码面试题:ArrayList源码分析面试你需要他
arraylist源码面试题:ArrayList源码分析面试你需要他/** * Constructs an empty list with the specified initial capacity. * * @param initialCapacity the initial capacity of the list * @throws IllegalArgumentException if the specified initial capacity * is negative * 指定容量的构造函数, */ public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[init
ArrayList源码如下这里我们分析下源码,首先要说的,我们面试讲源码主要还是将下源码的重点。下面我们来分析下重点。
[目标]:从类的基本信息、属性、构造函数、重要方法分析Arraylsit.
[详解]:顶部的注释给我们透露了几点重要信息:ArrayList是List接口的大小可变数组的实现;ArrayList允许null元素;ArrayList的容量可以自动增长;ArrayList不是同步的;ArrayList的iterator和listIterator方法返回的迭代器是fail-fast的.
首先:看下类的基本信息:
继承了AbstractList,实现了List、RandomAccess Cloneable Serializable接口
- 实现了List接口:ArrayList的父类AbstractList也实现了List接口,那为什么子类ArrayList还是去实现一遍呢?collection 的作者Josh说他写这代码的时候觉得这个会有用处,但是其实并没什么用,但因为没什么影响,就一直留到了现在。
- 实现了RandomAccess接口:表明ArrayList支持快速(通常是固定时间)随机访问。在ArrayList中,我们可以通过元素的序号快速获取元素对象,这就是快速随机访问。
- 实现了Cloneable接口:实现了该接口,就可以使用Object.Clone()方法了。 implements java.io.Serializable:表明该类具有序列化功能,该类可以被序列化,什么是序列化?简单的说,就是能够从类变成字节流传输,然后还能从字节流变成原来的类。
public class ArrayList<E> extends AbstractList<E>
implements List<E> RandomAccess Cloneable java.io.Serializable
{}
第二点是属性:
/**
* Default initial capacity.
* 初始化的容量
*/
private static final int DEFAULT_CAPACITY = 10;
/**
* Shared empty array instance used for empty instances.
* 指定该ArrayList容量为0时,返回该空数组。
*/
private static final Object[] EMPTY_ELEMENTDATA = {};
/**
* Shared empty array instance used for default sized empty instances. We
* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when
* first element is added.
* 调用无参构造方法时,默认返回改空数组;
* 这个和上面数组的区别就是:上面的是用户指定容量为0的时候返回的,当前的数组是默认构造函数返回的
*/
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
* 保存添加到ArrayList的元素
* 当ArrayList等于无参构造函数得到的数组时,当第一个元素添加时,容量将变成DEFAULT_CAPACITY
* ps:transient修饰此变量,不会序列化到
* 从这里我们可以看到,底层都是通过数组来存放元素的
*/
transient Object[] elementData; // non-private to simplify nested class access
/**
* The size of the ArrayList (the number of elements it contains).
* ArrayList的size
* @serial
*/
private int size;
/**
* The maximum size of array to allocate.
* Some vms reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
* 数组的最大容量,一些vm需要一些头部信息,所以会减8。超过MAX_ARRAY_SIZE会内存溢出
*
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
//备注:MAX.VALUE为0x7fffffff,转换成十进制就是2147483647,也就是数组的最大长度是2147483639;
第三:构造函数
(1)ArrayList(int initialCapacity):构造一个指定容量为capacity的空ArrayList。这是一个带初始容量大小的有参构造函数。 (2)无参构造函数:返回空数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA (3)ArrayList(Collection<? extends E> c):入参是集合,入参长度为0,返回空数组EMPTY_ELEMENTDATA;入参长度不是0,
/**
* Constructs an empty list with the specified initial capacity.
*
* @param initialCapacity the initial capacity of the list
* @throws IllegalArgumentException if the specified initial capacity
* is negative
* 指定容量的构造函数,
*/
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "
initialCapacity);
}
}
/**
* Constructs an empty list with an initial capacity of ten.
* 无参构造函数,默认返回空数组
*/
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
/**
* Constructs a list containing the elements of the specified
* collection in the order they are returned by the collection's
* iterator.
*
* @param c the collection whose elements are to be placed into this list
* @throws NullPointerException if the specified collection is null
* 根据一个集合,构造包含集合元素的ArrayList。他们将按照集合中迭代器的顺序返回
*/
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// defend against c.toArray (incorrectly) not returning Object[]
// (see e.g. https://bugs.openjdk.java.net/browse/JDK-6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData size Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
第四:重点方法
/**
* Appends the specified element to the end of this list.
* 添加指定的元素到list的末尾
* @param e element to be appended to this list
* @return <tt>true</tt> (as specified by {@link Collection#add})
*/
public boolean add(E e) {
ensureCapacityInternal(size 1); // Increments modCount!!
elementData[size ] = e;
return true;
}
//
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData minCapacity));
}
private void ensureExplicitCapacity(int minCapacity) {
modCount ;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
/**
* Increases the capacity to ensure that it can hold at least the
* number of elements specified by the minimum capacity argument.
*
* @param minCapacity the desired minimum capacity
*/
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size so this is a win:
elementData = Arrays.copyOf(elementData newCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}