ArrayList源码解析

一、简介:

讲解的版本是JDK 1.8。ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。

二、重要成员变量:

transient Object[] elementData:保存元素

private int size:当前保存的元素数量

private static final int DEFAULT_CAPACITY = 10:默认数组大小

三、构造方法:

arrayList有三个构造方法,看下最只要的:

 1     public ArrayList(int initialCapacity) {
 2         if (initialCapacity > 0) {
 3             this.elementData = new Object[initialCapacity];
 4         } else if (initialCapacity == 0) {
 5             this.elementData = EMPTY_ELEMENTDATA;
 6         } else {
 7             throw new IllegalArgumentException("Illegal Capacity: "+
 8                                                initialCapacity);
 9         }
10     }

initialCapacity为传入的初始容量,如果大于0,则创建数组,否则,使用默认大小为0的数组;

四、重要的方法:

1.add():

 1           public boolean add(E e) {
 2                   //检查是否越界
 3                 ensureCapacityInternal(size + 1);  // Increments modCount!!
 4                 //插入元素
 5                 elementData[size++] = e;
 6                 return true;
 7             }
 8           
 9            private void ensureCapacityInternal(int minCapacity) {
10                    //如果是开始起始时的空数组,则在默认容量和minCapacity中选择较大的
11                 if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
12                     minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
13                 }
14 
15                 ensureExplicitCapacity(minCapacity);
16             }
17            private void ensureExplicitCapacity(int minCapacity) {
18                 modCount++;
19 
20                 // overflow-conscious code
21                 //如果当前需要的大小大于数组总容量,则对数组扩容
22                 if (minCapacity - elementData.length > 0)
23                     grow(minCapacity);
24             }
25            
26             private void grow(int minCapacity) {
27                 // overflow-conscious code
28                 int oldCapacity = elementData.length;
29                 //计算新容量
30                 int newCapacity = oldCapacity + (oldCapacity >> 1);
31                 //如果新容量还是小于需要的大小,则使用需要的大小作为新容量
32                 if (newCapacity - minCapacity < 0)
33                     newCapacity = minCapacity;
34                 if (newCapacity - MAX_ARRAY_SIZE > 0)
35                     newCapacity = hugeCapacity(minCapacity);
36                 // minCapacity is usually close to size, so this is a win:
37                 //将原数组拷贝到创建的数组中然后赋值给elementData,最终调用System.arraycopy()来完成
38                 elementData = Arrays.copyOf(elementData, newCapacity);
39             }

代码关键部分都做了注释,就不在解释了。

2.get():

 1             public E get(int index) {
 2                 //检查索引是否越界
 3                 rangeCheck(index);
 4                 //直接返回元素
 5                 return elementData(index);
 6             }
 7             private void rangeCheck(int index) {
 8                 if (index >= size)
 9                     throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
10             }

3.remove(int index):

 1             public E remove(int index) {
 2                 //检查数组是否越界
 3                 rangeCheck(index);
 4 
 5                 modCount++;
 6                 获取要删除的元素
 7                 E oldValue = elementData(index);
 8                 //计算要移动的元素数量
 9                 int numMoved = size - index - 1;
10                 if (numMoved > 0)
11                     //将被删除元素后面的所有元素向前移动一个位置
12                     System.arraycopy(elementData, index+1, elementData, index,
13                                      numMoved);
14                 elementData[--size] = null; // clear to let GC do its work
15                 //返回被删除的元素
16                 return oldValue;
17             }

这样基本的操作就讲完了,还是挺简单的吧。

 

posted @ 2016-04-15 22:35  gatsbydhn  阅读(185)  评论(0编辑  收藏  举报