ArrayList是平时使用很多的一个类,趁有时间,我也阅读以下源码,以帮助自己加深理解。类的层次结构这里就不列出了,主要分析一下源码部分,
属性部分:
protected transient int modCount = 0; //这个属性是从AbstractList继承过来的,每次ArrayList进行结构变化时都会+1.下面会从源码角度去分析这个属性.
private static final int DEFAULT_CAPACITY = 10; //这个属性是默认初始容量大小
private static final Object[] EMPTY_ELEMENTDATA = {}; //空数组,声明为static final,每个空的ArrayList实例都能共享此属性,节省了内存开支,这种设计值得学习;
private transient Object[] elementData; //Object[]数组类型,存放的元素内容
private int size; //所保存的元素的个数
构造函数部分:
public ArrayList() {
super(); //先调用AbstractList的构造函数
this.elementData = EMPTY_ELEMENTDATA; //默认为空对象数组
}
public ArrayList(int initialCapacity) {
super(); //先调用AbstractList的构造函数
if (initialCapacity < 0) //小于0时抛异常,因为该异常是继承RuntimeException,运行时异常,所以平时试用时没有强制要求我们捕获处理
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
this.elementData = new Object[initialCapacity]; //初始化initialCapacity大小的对象数组,并将elementData引用指向此数组
}
public ArrayList(Collection<? extends E> c) { //使用继承Collection的集合对象来创建ArrayList
elementData = c.toArray();
size = elementData.length;
// c.toArray might (incorrectly) not return Object[] (see 6260652)
<span style="white-space:pre"> </span>//这里是有可能c.toArray()会失败,这是一个bug,bug编号为 6260652,
if (elementData.getClass() != Object[].class) //使用转化失败的补充动作
elementData = Arrays.copyOf(elementData, size, Object[].class);
}
方法部分:
public void trimToSize() { //该方法是调整ArrayList的容器大小至所容纳容器元素数量一样。通俗的讲也就是把ArrayList中null所占的位置去掉。
modCount++; //涉及到ArrayList结构的调整,所以modCount++
if (size < elementData.length) {
elementData = Arrays.copyOf(elementData, size); //进行拷贝复制,Arrays.copyOf方法也是比较核心的方法,以后再细看源码进行分析。
}
}
接下来讲讲与ArrayList扩容相关的方法
<pre name="code" class="java">public void ensureCapacity(int minCapacity) { //可以调用该方法为ArrayList扩容,
int minExpand = (elementData != EMPTY_ELEMENTDATA) //如果elementData不是空数组,则minExpand(最小扩展数)为0,为空数组(注意区分[null,null]与[]得区别)的话默认最小扩展数为10,
// any size if real element table
? 0
// larger than default for empty table. It's already supposed to be
// at default size.
: DEFAULT_CAPACITY;
if (minCapacity > minExpand) { //要扩容的大小符合最小扩展数
ensureExplicitCapacity(minCapacity);
}
}
</pre><pre name="code" class="java"> private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!<span style="font-family: Arial, Helvetica, sans-serif;">//每次调用add时,都会调用 检查容器容量,具体具体代码如下</span>
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}//保证ArrayList最小容量最10
ensureExplicitCapacity(minCapacity);
}
private void grow(int minCapacity) { //最终通过调用此方法进行扩容,该算法描述保证要扩展至原来的1/2大小,如果要扩展的内容大于原来的1/2,则按照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);
}
先停止一下,哎第一次写博客,把东西写出来不是一件容易事啊,坚持补充完下班后。