【小笨鸟看JDK1.7集合源码之二】ArrayList源码剖析

  主要是参考大神兰亭风雨的博客;

  ArrayList简介 

 (1) ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。

   (2) ArrayList不是线程安全的,只能用在单线程环境下,多线程环境下可以考虑用Collections.synchronizedList(List l)函数返回一个线程安全的ArrayList类,也可以使用concurrent并发包下的CopyOnWriteArrayList类。

   (3) ArrayList实现了Serializable接口,因此它支持序列化,能够通过序列化传输,实现了RandomAccess接口,支持快速随机访问,实际上就是通过下标序号进行快速访问,实现了Cloneable接口,能被克隆。

 ArrayList(JDK1.7)源码详细剖析注释

  1 package java.util;
  2 
  3 /**
  4  * JDK1.7
  5  * @author foolishbird_lmy
  6  *
  7  */
  8 public class ArrayList<E> extends AbstractList<E>
  9         implements List<E>, RandomAccess, Cloneable, java.io.Serializable
 10 {
 11     //自动生成的序列版本号,主要用于版本的兼容问题
 12     private static final long serialVersionUID = 8683452581122892189L;
 13 
 14     //默认的容量,用于每次数组的自动扩展
 15     private static final int DEFAULT_CAPACITY = 10;
 16 
 17     //定义的一个默认空数组对象
 18     private static final Object[] EMPTY_ELEMENTDATA = {};
 19 
 20    //ArrayList是基于数组结构来实现的,该数组用来实际保存数据,transient这个关键字是声明改变量不能被序列化
 21     private transient Object[] elementData;
 22 
 23     //当前集合中实际的元素的个数即大小
 24     private int size;
 25 
 26     //带参数的构造函数,initialCapacity,初始化的容量即需要构造的List的大小
 27     public ArrayList(int initialCapacity) {
 28         super();
 29         if (initialCapacity < 0)
 30             throw new IllegalArgumentException("Illegal Capacity: "+
 31                                                initialCapacity);
 32         this.elementData = new Object[initialCapacity];
 33     }
 34 
 35    //无参构造函数初始化,注意是根据默认大小限定为10,即你不传参数时也会构造大小为10的List
 36     public ArrayList() {
 37         super();
 38         this.elementData = EMPTY_ELEMENTDATA;
 39     }
 40 
 41     /*
 42     *创建一个包含Collection类型的ArrayList,实际的过程是首先根据Collection中的元素复制一个数组
 43     */
 44     public ArrayList(Collection<? extends E> c) {
 45         elementData = c.toArray();//返回包含此 collection 中所有元素的数组。
 46         size = elementData.length;//数组的长度
 47         if (elementData.getClass() != Object[].class)//判断是否为数组类型
 48             elementData = Arrays.copyOf(elementData, size, Object[].class);//Arrays工具类,复制数组
 49     }
 50     //将此 ArrayList 实例的容量调整为列表的当前大小,即根据当前的实际数组元素的长度设置容量
 51     public void trimToSize() {
 52         modCount++;
 53         /*这个参数仔细查了一下,是父类AbstractList中定义了一个int型的属性:modCount,记录了ArrayList结构性变化的次数
 54         包括:add()、remove()、addAll()、removeRange()及clear()方法。这些方法每调用一次,modCount的值就加1。
 55         主要的作用就是在迭代的时候保持单线程的安全性;只要是容量发生变化这个参数就会自动随着变化
 56         */
 57         if (size < elementData.length) {
 58             elementData = Arrays.copyOf(elementData, size);
 59         }
 60     }
 61 
 62     /*
 63     如有必要,增加此 ArrayList 实例的容量,以确保它至少能够容纳最小容量参数所指定的元素数.
 64     DEFAULT_CAPACITY 默认的最小值10
 65     EMPTY_ELEMENTDATA 默认为空
 66     */
 67     //这个方法的主要作用是确定当前集合的容量是否足够,minCapacity参数是所需的最小容量,如果小于则扩容
 68     public void ensureCapacity(int minCapacity) {
 69         //三目运算,如果elementData为空,则minExpand=DEFAULT_CAPACITY=10,否则取0
 70         int minExpand = (elementData != EMPTY_ELEMENTDATA)? 0: DEFAULT_CAPACITY;
 71         //如果小于则扩容
 72         if (minCapacity > minExpand) {
 73             ensureExplicitCapacity(minCapacity);
 74         }
 75         //如果大于,说明容量足够
 76     }
 77     
 78     //这个是1.7之后新加入的,主要是为了内部确保集合容量,与ensureCapacity相似,但是一个是public可以供外部使用,一个是private供内部使用
 79     private void ensureCapacityInternal(int minCapacity) {
 80         if (elementData == EMPTY_ELEMENTDATA) {
 81             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
 82         }
 83         ensureExplicitCapacity(minCapacity);
 84     }
 85 
 86     private void ensureExplicitCapacity(int minCapacity) {
 87         modCount++;
 88 
 89         // 如果当前的实际容量小于需要的最小容量,则扩容
 90         if (minCapacity - elementData.length > 0)
 91             grow(minCapacity);
 92     }
 93     //    这里定义了一个最大的数组长度,为什么会减8个字节了,我查了一下,
 94     // as the Array it self needs 8 bytes to stores the size  2,147,483,648
 95     //暂且理解的意思是需要8个字节来存储数组的长度值,其实这个主要也是由虚拟机决定。
 96     
 97     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 98     /*
 99         这个是扩容的实现;这里要注意一下,每次的扩容其实是到之前的1.5倍;
100         oldCapacity + (oldCapacity >> 1) 实际上就是右移除2 结果是3/2oldCapacity
101     */
102     private void grow(int minCapacity) {
103         // overflow-conscious code
104         int oldCapacity = elementData.length;
105         int newCapacity = oldCapacity + (oldCapacity >> 1);
106         if (newCapacity - minCapacity < 0)
107             newCapacity = minCapacity;
108         if (newCapacity - MAX_ARRAY_SIZE > 0)
109             newCapacity = hugeCapacity(minCapacity);
110         // minCapacity is usually close to size, so this is a win:
111         elementData = Arrays.copyOf(elementData, newCapacity);
112     }
113     //用来判断是否超出数组最大范围
114     private static int hugeCapacity(int minCapacity) {
115         if (minCapacity < 0) // overflow
116             throw new OutOfMemoryError();
117         return (minCapacity > MAX_ARRAY_SIZE) ?
118             Integer.MAX_VALUE :
119             MAX_ARRAY_SIZE;
120     }
121 
122    //返回ArrayList的实际大小 
123     public int size() {
124         return size;
125     }
126 
127     //判断ArrayList是否为空
128     public boolean isEmpty() {
129         return size == 0;
130     }
131 
132     //判断是否包含某个元素
133     public boolean contains(Object o) {
134         return indexOf(o) >= 0;
135     }
136 
137     //从头开始查找某个元素,返回元素的索引值,注意,我们从源码中可以看到,是可以查找空值的。。并且没有找到是返回-1
138     public int indexOf(Object o) {
139         if (o == null) {
140             for (int i = 0; i < size; i++)
141                 if (elementData[i]==null)
142                     return i;
143         } else {
144             for (int i = 0; i < size; i++)
145                 if (o.equals(elementData[i]))
146                     return i;
147         }
148         return -1;
149     }
150 
151  //反向从最后开始查找,与上面相反
152     public int lastIndexOf(Object o) {
153         if (o == null) {
154             for (int i = size-1; i >= 0; i--)
155                 if (elementData[i]==null)
156                     return i;
157         } else {
158             for (int i = size-1; i >= 0; i--)
159                 if (o.equals(elementData[i]))
160                     return i;
161         }
162         return -1;
163     }
164 
165     //执行克隆,注意这是一个浅克隆,并没有复制数组去创建一个新的,只是将一个新引用指向同一个对象而已。
166     public Object clone() {
167         try {
168             @SuppressWarnings("unchecked")
169                 ArrayList<E> v = (ArrayList<E>) super.clone();
170             v.elementData = Arrays.copyOf(elementData, size);
171             v.modCount = 0;
172             return v;
173         } catch (CloneNotSupportedException e) {
174             // this shouldn't happen, since we are Cloneable
175             throw new InternalError();
176         }
177     }
178 
179   //返回集合中元素以数组形式
180     public Object[] toArray() {
181         return Arrays.copyOf(elementData, size);
182     }
183 
184     //以指定T类型数组形式返回
185     @SuppressWarnings("unchecked")
186     public <T> T[] toArray(T[] a) {
187         //如果数组a的大小<集合的大小,也就是元素的个数
188         if (a.length < size)
189             // 返回一个新的T类型的数组,将集合中的元素全部拷贝过去
190             return (T[]) Arrays.copyOf(elementData, size, a.getClass());
191         //否则数组a的大小>=集合的大小,则直接将集合中的数组全部拷贝到数组a中去
192         System.arraycopy(elementData, 0, a, 0, size);
193         //注意:因为数组此时大小是大于集合中的元素的,拷贝之后会有剩余的空间,全部设置为null
194         if (a.length > size)
195             a[size] = null;
196         return a;
197     }
198 
199  //返回指定下标的元素
200     @SuppressWarnings("unchecked")
201     E elementData(int index) {
202         return (E) elementData[index];
203     }
204 
205  //返回指定下标的元素
206     public E get(int index) {
207         rangeCheck(index);//这个方法主要是检查下标是否越界
208 
209         return elementData(index);
210     }
211 
212    //设置指定下标的值
213     public E set(int index, E element) {
214         rangeCheck(index);//这个方法主要是检查下标是否越界
215         //先找到指定位置值
216         E oldValue = elementData(index);
217         elementData[index] = element;
218         return oldValue;
219     }
220 
221    //从尾部添加元素
222     public boolean add(E e) {
223         //先扩容
224         ensureCapacityInternal(size + 1);  // Increments modCount!!
225         elementData[size++] = e;
226         return true;
227     }
228 
229    //在指定的下标添加元素
230     public void add(int index, E element) {
231         rangeCheckForAdd(index);//是否越界
232         //扩容
233         ensureCapacityInternal(size + 1);  // Increments modCount!!
234         //第一个elementData代表源数组,index代表从此下标开始截取,第二个elementData代表现在的目标数组,会将前面截取的数组从下标index + 1处开始覆盖
235     //例如数组{1,2,3,4,5} index=1 ,截取长度size - index为4,则第一个截取为{2,3,4,5},然后从index=2开始覆盖,得到{1,2,2,3,4,5,6}此时数组已经扩容了
236     //最后设置index=1处值即可,完成添加
237         System.arraycopy(elementData, index, elementData, index + 1,
238                          size - index);
239         elementData[index] = element;
240         size++;
241     }
242 
243 //删除指定位置的元素并返回元素的值   
244     public E remove(int index) {
245         rangeCheck(index);//看下标是否越界
246 
247         modCount++;
248         
249         E oldValue = elementData(index);//保存删除的元素
250 
251         int numMoved = size - index - 1;//代表在index下标之后的全部元素的数量
252         if (numMoved > 0)//如果index不是最后一个元素
253             //采用复制数组的方式将index覆盖删除
254             System.arraycopy(elementData, index+1, elementData, index,
255                              numMoved);
256         elementData[--size] = null; //注意最后还要将最后一个元素设置为空,这是一个多余的重复元素
257 
258         return oldValue;
259     }
260 
261     //删除指定位置的元素,返回是否成功
262     public boolean remove(Object o) {
263         //这个比较清晰,注意内部将空的元素与非空元素分开处理的,不过都是从头到尾扫描
264         if (o == null) {
265             for (int index = 0; index < size; index++)
266                 if (elementData[index] == null) {
267                     fastRemove(index);//如果确认存在这个元素,调用的快速删除
268                     return true;
269                 }
270         } else {
271             for (int index = 0; index < size; index++)
272                 if (o.equals(elementData[index])) {
273                     fastRemove(index);
274                     return true;
275                 }
276         }
277         return false;
278     }
279 
280    //已经确认了存在要删除的元素,就直接找到删除,与remove()方法内部一样
281     private void fastRemove(int index) {
282         modCount++;
283         int numMoved = size - index - 1;
284         if (numMoved > 0)
285             System.arraycopy(elementData, index+1, elementData, index,
286                              numMoved);
287         elementData[--size] = null; // clear to let GC do its work
288     }
289 
290     //清空集合内部所有的元素,遍历设置为空
291     public void clear() {
292         modCount++;
293 
294         // clear to let GC do its work
295         for (int i = 0; i < size; i++)
296             elementData[i] = null;
297 
298         size = 0;
299     }
300 
301     //将Collection容器中的元素全部以迭代的方式添加到此列表的尾部
302     public boolean addAll(Collection<? extends E> c) {
303         Object[] a = c.toArray();//复制数组
304         int numNew = a.length;//长度
305         ensureCapacityInternal(size + numNew);  // 扩容,准备添加到列表尾部
306         //取数组a,从0下标开始,长度为numNew,来覆盖数组elementData,下标从size开始,即从最后开始尾部添加
307         System.arraycopy(a, 0, elementData, size, numNew);
308         size += numNew;//添加完后要相应长度增加
309         return numNew != 0;//如果参数中的容器元素为空,返回false,否则返回true
310     }
311 
312     //从指定位置index处开始添加元素
313     public boolean addAll(int index, Collection<? extends E> c) {
314         //与rangeCheck方法功能相似,也是判断下标是否越界,些许的区别是允许边界判断允许等于长度即从尾部开始添加,当然必须大于0啦
315         rangeCheckForAdd(index);
316 
317         Object[] a = c.toArray();
318         int numNew = a.length;
319         ensureCapacityInternal(size + numNew);  // 这三句与上面一样
320 
321         /*我还是习惯用实例来分析,假设现在我们本来的列表为elementData={1,3,5,7,9}
322         参数index=1,a={2,4,6,8},则numMoved = size - index=size + numNew-index=8 注意这里已经扩容了,不然下面的复制操作会报
323         ArrayIndexOutOfBoundsException异常;即现在新的elementData={1,3,5,7,9,null,null,null,null}
324         开始逐步分析:
325         执行这句System.arraycopy(elementData, index, elementData, index + numNew,numMoved);
326         (1)elementData中从index(包括index)取numMoved长度的数组,即{3,5,7,9,null,null,null,null}
327         (2)elementData中从index + numNew = 5处(包括index + numNew)开始执行覆盖,即{1,3,5,7,9,3,5,7,9}后面的null舍弃.
328         执行System.arraycopy(a, 0, elementData, index, numNew);
329         (1)a数组中从0开始取numNew长度数组,即{2,4,6,8}
330         (2)elementData从index=1处(包括index)开始执行覆盖,即{1,2,4,6,8,3,5,7,9}
331         全部过程执行完毕,实现了从index插入数组。
332         */
333         int numMoved = size - index;//这是为了准备取index之后的元素
334         if (numMoved > 0)
335             System.arraycopy(elementData, index, elementData, index + numNew,
336                              numMoved);
337 
338         System.arraycopy(a, 0, elementData, index, numNew);
339         size += numNew; 
340         return numNew != 0;//如果参数中的容器元素为空,返回false,否则返回true
341     }
342 
343     //删除指定位置范围内的元素,从fromIndex(包括)到toIndex(不包括)
344     protected void removeRange(int fromIndex, int toIndex) {
345         modCount++;
346         int numMoved = size - toIndex;
347         //此处分析过程与上面一样
348         System.arraycopy(elementData, toIndex, elementData, fromIndex,
349                          numMoved);
350 
351         // clear to let GC do its work
352         int newSize = size - (toIndex-fromIndex);
353         for (int i = newSize; i < size; i++) {
354             elementData[i] = null;//从这里可以看出其实集合中的实际容量并不止这些,还有将后面的闲置的空间设置为空,便于GC去回收
355         }
356         size = newSize;//删除后要更新长度
357     }
358 
359      //根据源码的注释说明,这个方法并不会检查index为负数的情况,但是它会在访问数组之前,直接抛出ArrayIndexOutOfBoundsException异常
360     private void rangeCheck(int index) {
361         if (index >= size)
362             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
363     }
364 
365      //主要是给add and addAll两个方法判断下标是否越界使用
366     private void rangeCheckForAdd(int index) {
367         if (index > size || index < 0)
368             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
369     }
370 
371   //主要用于抛出异常时定位详细信息
372     private String outOfBoundsMsg(int index) {
373         return "Index: "+index+", Size: "+size;
374     }
375 
376    
377      //删除指定Collection中包含的元素,即只要是Collection中含有的元素,在列表中进行删除操作,会得到一个新的列表
378     public boolean removeAll(Collection<?> c) {
379         return batchRemove(c, false);
380     }
381 
382    //与上面的方法相反,仅仅保留Collection中含有的元素,相当于两个列表取交集
383     public boolean retainAll(Collection<?> c) {
384         return batchRemove(c, true);
385     }
386 
387     //这个内部方法只分析false过程,true过程相似
388     private boolean batchRemove(Collection<?> c, boolean complement) {
389         final Object[] elementData = this.elementData;//获得列表中的数组
390         int r = 0, w = 0;
391         boolean modified = false;
392         try {
393             for (; r < size; r++)//遍历列表,如果参数complement传进来默认为fasle
394                 if (c.contains(elementData[r]) == complement)//变量列表中的所有元素是否存在与c中
395                     elementData[w++] = elementData[r];//如果不存在,则将不存在的元素存放在elementData中前列,也就是从头开始覆盖掉与c中重复的元素只保留不同的元素
396             //这个其实就是找出两个列表中的不同元素放在原始列表的前段,相当于去除了相同的元素;
397             //如果参数为true,则是找出两个列表中的相同元素放在原始列表的前段,相当于取出了交集元素;
398         } finally {
399             // Preserve behavioral compatibility with AbstractCollection,
400             // even if c.contains() throws.
401             if (r != size) {
402                 //finally中的功能实际上是通过复制覆盖截取列表前段已经找出来的不同元素
403                 System.arraycopy(elementData, r,
404                                  elementData, w,
405                                  size - r);
406                 w += size - r;
407             }
408             if (w != size) {
409                 // 主要是为了将列表后半段相同的元素置NULL,便于GC回收
410                 for (int i = w; i < size; i++)
411                     elementData[i] = null;
412                 modCount += size - w;
413                 size = w;//更新列表中的实际元素个数即长度
414                 modified = true;
415             }
416         }
417         return modified;
418     }
419     // java.io.Serializable的写入函数    
420     // 将ArrayList的“容量,所有的元素值”都写入到输出流中 
421     private void writeObject(java.io.ObjectOutputStream s)
422         throws java.io.IOException{
423      
424         int expectedModCount = modCount;//记录标记
425         s.defaultWriteObject();
426         //写入“数组的容量” 
427         s.writeInt(size);
428 
429         // 写入列表中的每一个元素
430         for (int i=0; i<size; i++) {
431             s.writeObject(elementData[i]);
432         }
433         //这个变量我理解的是防止在写入输出流的同时,又在进行列表的删除或添加操作,保证单线程安全问题;
434         if (modCount != expectedModCount) {
435             throw new ConcurrentModificationException();
436         }
437     }
438 
439     //与上面的对应,读取输出流
440     private void readObject(java.io.ObjectInputStream s)
441         throws java.io.IOException, ClassNotFoundException {
442         elementData = EMPTY_ELEMENTDATA;//默认为空
443         
444         s.defaultReadObject();
445 
446         s.readInt(); // 从输入流中读取列表容量
447 
448         if (size > 0) {
449             // 确保实际容量
450             ensureCapacityInternal(size);
451 
452             Object[] a = elementData;
453             // 将输入流中的所有元素读取出来并赋值
454             for (int i=0; i<size; i++) {
455                 a[i] = s.readObject();
456             }
457         }
458     }
459 
460     //迭代器
461     public ListIterator<E> listIterator(int index) {
462         if (index < 0 || index > size)
463             throw new IndexOutOfBoundsException("Index: "+index);
464         return new ListItr(index);
465     }
466 
467     public ListIterator<E> listIterator() {
468         return new ListItr(0);
469     }
470 
471     public Iterator<E> iterator() {
472         return new Itr();
473     }
474     /*Itr内部类,实现了Iterator接口,主要是实现迭代器的功能,也就是设计模式适配器思想,用于迭代出列表中的全部元素,*/
475     private class Itr implements Iterator<E> {
476         int cursor;       // 默认的返回迭代的下一个元素索引
477         int lastRet = -1; // 默认的返回最后一个元素的索引,如果数组为空直接返回-1
478         int expectedModCount = modCount;
479         //是否还存在下一个元素,即是否迭代到列表尾部
480         public boolean hasNext() {
481             return cursor != size;//迭代到尾部返回true,否则返回false
482         }
483 
484         //获取下一个元素值
485         @SuppressWarnings("unchecked")
486         public E next() {
487             checkForComodification();//检查线程安全,迭代同时列表是否改变
488             int i = cursor;
489             if (i >= size)//先判断是否超出列表容量
490                 throw new NoSuchElementException();
491             Object[] elementData = ArrayList.this.elementData;//获取列表元素数组
492             if (i >= elementData.length)
493                 throw new ConcurrentModificationException();
494             cursor = i + 1;//记住指向下一个元素索引,便于下次迭代
495             return (E) elementData[lastRet = i];//更新lastRet值
496         }
497         //从尾部开始删除
498         public void remove() {
499             if (lastRet < 0)//其实就是-1,则列表为空
500                 throw new IllegalStateException();
501             checkForComodification();
502 
503             try {
504                 ArrayList.this.remove(lastRet);//从最后开始删除
505                 cursor = lastRet;
506                 lastRet = -1;
507                 expectedModCount = modCount;
508             } catch (IndexOutOfBoundsException ex) {
509                 throw new ConcurrentModificationException();
510             }
511         }
512 
513         final void checkForComodification() {
514             if (modCount != expectedModCount)
515                 throw new ConcurrentModificationException();
516         }
517     }
518     /*ListItr内部类,继承了Itr类,实现了迭代器功能,主要是继承了ListIterator接口
519     系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。
520     ListIterator 没有当前元素;它的光标位置 始终位于调用 previous() 所返回的元素和调用 next() 所返回的元素之间。
521     长度为 n 的列表的迭代器有 n+1 个可能的指针位置
522     */
523     private class ListItr extends Itr implements ListIterator<E> {
524         //带参数的构造函数
525         ListItr(int index) {
526             super();
527             cursor = index;
528         }
529         /*如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
530         换句话说,如果 previous 返回一个元素而不是抛出异常,则返回 true)。 
531         其实就是确定当前迭代出的元素是否有前任元素,当迭代出的是第一个元素时,
532         */
533         public boolean hasPrevious() {
534             return cursor != 0;
535         }
536         //返回下一个元素的索引,如果迭代到列表的尾部,则返回列表的大小
537         public int nextIndex() {
538             return cursor;
539         }
540         //返回当前迭代元素的
541         public int previousIndex() {
542             return cursor - 1;
543         }
544 
545         @SuppressWarnings("unchecked")
546         public E previous() {
547             checkForComodification();
548             int i = cursor - 1;
549             if (i < 0)
550                 throw new NoSuchElementException();
551             Object[] elementData = ArrayList.this.elementData;
552             if (i >= elementData.length)
553                 throw new ConcurrentModificationException();
554             cursor = i;
555             return (E) elementData[lastRet = i];
556         }
557 
558         public void set(E e) {
559             if (lastRet < 0)
560                 throw new IllegalStateException();
561             checkForComodification();
562 
563             try {
564                 ArrayList.this.set(lastRet, e);
565             } catch (IndexOutOfBoundsException ex) {
566                 throw new ConcurrentModificationException();
567             }
568         }
569 
570         public void add(E e) {
571             checkForComodification();
572 
573             try {
574                 int i = cursor;
575                 ArrayList.this.add(i, e);
576                 cursor = i + 1;
577                 lastRet = -1;
578                 expectedModCount = modCount;
579             } catch (IndexOutOfBoundsException ex) {
580                 throw new ConcurrentModificationException();
581             }
582         }
583     }
584 
585     //返回一个新的列表,范围是fromIndex到toIndex
586     public List<E> subList(int fromIndex, int toIndex) {
587         subListRangeCheck(fromIndex, toIndex, size);
588         //直接用构造函数构建
589         return new SubList(this, 0, fromIndex, toIndex);
590     }
591     //检查下标的范围是否越界
592     static void subListRangeCheck(int fromIndex, int toIndex, int size) {
593         if (fromIndex < 0)
594             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
595         if (toIndex > size)
596             throw new IndexOutOfBoundsException("toIndex = " + toIndex);
597         if (fromIndex > toIndex)
598             throw new IllegalArgumentException("fromIndex(" + fromIndex +
599                                                ") > toIndex(" + toIndex + ")");
600     }
601     /*
602         SubList内部类,继承了AbstractList抽象类,AbstractList实现了AbstractCollection,适配器设计模式;
603         实现了RandomAccess接口支持随机访问;
604     */
605     private class SubList extends AbstractList<E> implements RandomAccess {
606         private final AbstractList<E> parent;//原始列表
607         private final int parentOffset;//原始列表的偏移量
608         private final int offset;//偏移量
609         int size;
610         //构造函数初始化
611         SubList(AbstractList<E> parent,
612                 int offset, int fromIndex, int toIndex) {
613             this.parent = parent;
614             this.parentOffset = fromIndex;//初始化为要截取列表的开始下标
615             this.offset = offset + fromIndex;//初始化为要截取列表的开始下标,这里假定从原始列表的头开始算,初始偏移量为0
616             this.size = toIndex - fromIndex;//截取的长度
617             this.modCount = ArrayList.this.modCount;
618         }
619         //设置指定下标的值
620         public E set(int index, E e) {
621             rangeCheck(index);
622             checkForComodification();
623             E oldValue = ArrayList.this.elementData(offset + index);
624             ArrayList.this.elementData[offset + index] = e;//注意这里还要加上偏移量,因为可能有时候并不是从第一个元素开始;
625             return oldValue;//并返回被覆盖的元素
626         }
627         //获取指定下标的值,并返回值
628         public E get(int index) {
629             rangeCheck(index);
630             checkForComodification();
631             return ArrayList.this.elementData(offset + index);
632         }
633         //获取当前列表长度
634         public int size() {
635             checkForComodification();
636             return this.size;
637         }
638         //在指定位置添加元素
639         public void add(int index, E e) {
640             rangeCheckForAdd(index);
641             checkForComodification();
642             parent.add(parentOffset + index, e);
643             this.modCount = parent.modCount;
644             this.size++;
645         }
646         //删除指定下标的元素
647         public E remove(int index) {
648             rangeCheck(index);
649             checkForComodification();
650             E result = parent.remove(parentOffset + index);
651             this.modCount = parent.modCount;
652             this.size--;
653             return result;
654         }
655         //删除指定范围内的元素
656         protected void removeRange(int fromIndex, int toIndex) {
657             checkForComodification();
658             //调用的是AbstractList中的removeRange方法,采用迭代逐一删除元素
659             parent.removeRange(parentOffset + fromIndex,
660                                parentOffset + toIndex);
661             this.modCount = parent.modCount;
662             this.size -= toIndex - fromIndex;
663         }
664         //将c中的元素全部添加到当前列表的尾部
665         public boolean addAll(Collection<? extends E> c) {
666             return addAll(this.size, c);
667         }
668         //将c中的元素全部添加到当前列表的指定index位置
669         public boolean addAll(int index, Collection<? extends E> c) {
670             rangeCheckForAdd(index);
671             int cSize = c.size();
672             if (cSize==0)
673                 return false;//为null直接返回
674 
675             checkForComodification();
676             parent.addAll(parentOffset + index, c);
677             this.modCount = parent.modCount;
678             this.size += cSize;
679             return true;
680         }
681         
682         public Iterator<E> iterator() {
683             return listIterator();
684         }
685 
686         public ListIterator<E> listIterator(final int index) {
687             checkForComodification();
688             rangeCheckForAdd(index);
689             final int offset = this.offset;
690 
691             return new ListIterator<E>() {
692                 int cursor = index;
693                 int lastRet = -1;
694                 int expectedModCount = ArrayList.this.modCount;
695 
696                 public boolean hasNext() {
697                     return cursor != SubList.this.size;
698                 }
699 
700                 @SuppressWarnings("unchecked")
701                 public E next() {
702                     checkForComodification();
703                     int i = cursor;
704                     if (i >= SubList.this.size)
705                         throw new NoSuchElementException();
706                     Object[] elementData = ArrayList.this.elementData;
707                     if (offset + i >= elementData.length)
708                         throw new ConcurrentModificationException();
709                     cursor = i + 1;
710                     return (E) elementData[offset + (lastRet = i)];
711                 }
712 
713                 public boolean hasPrevious() {
714                     return cursor != 0;
715                 }
716 
717                 @SuppressWarnings("unchecked")
718                 public E previous() {
719                     checkForComodification();
720                     int i = cursor - 1;
721                     if (i < 0)
722                         throw new NoSuchElementException();
723                     Object[] elementData = ArrayList.this.elementData;
724                     if (offset + i >= elementData.length)
725                         throw new ConcurrentModificationException();
726                     cursor = i;
727                     return (E) elementData[offset + (lastRet = i)];
728                 }
729 
730                 public int nextIndex() {
731                     return cursor;
732                 }
733 
734                 public int previousIndex() {
735                     return cursor - 1;
736                 }
737 
738                 public void remove() {
739                     if (lastRet < 0)
740                         throw new IllegalStateException();
741                     checkForComodification();
742 
743                     try {
744                         SubList.this.remove(lastRet);
745                         cursor = lastRet;
746                         lastRet = -1;
747                         expectedModCount = ArrayList.this.modCount;
748                     } catch (IndexOutOfBoundsException ex) {
749                         throw new ConcurrentModificationException();
750                     }
751                 }
752 
753                 public void set(E e) {
754                     if (lastRet < 0)
755                         throw new IllegalStateException();
756                     checkForComodification();
757 
758                     try {
759                         ArrayList.this.set(offset + lastRet, e);
760                     } catch (IndexOutOfBoundsException ex) {
761                         throw new ConcurrentModificationException();
762                     }
763                 }
764 
765                 public void add(E e) {
766                     checkForComodification();
767 
768                     try {
769                         int i = cursor;
770                         SubList.this.add(i, e);
771                         cursor = i + 1;
772                         lastRet = -1;
773                         expectedModCount = ArrayList.this.modCount;
774                     } catch (IndexOutOfBoundsException ex) {
775                         throw new ConcurrentModificationException();
776                     }
777                 }
778 
779                 final void checkForComodification() {
780                     if (expectedModCount != ArrayList.this.modCount)
781                         throw new ConcurrentModificationException();
782                 }
783             };
784         }
785         //返回原始列表范围的部分列表,从fromIndex(包括)开始,到toIndex(不包括)
786         public List<E> subList(int fromIndex, int toIndex) {
787             subListRangeCheck(fromIndex, toIndex, size);
788             return new SubList(this, offset, fromIndex, toIndex);
789         }
790         
791         private void rangeCheck(int index) {
792             if (index < 0 || index >= this.size)
793                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
794         }
795 
796         private void rangeCheckForAdd(int index) {
797             if (index < 0 || index > this.size)
798                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
799         }
800 
801         private String outOfBoundsMsg(int index) {
802             return "Index: "+index+", Size: "+this.size;
803         }
804 
805         private void checkForComodification() {
806             if (ArrayList.this.modCount != this.modCount)
807                 throw new ConcurrentModificationException();
808         }
809     }
810 }

   还是总结一下

(1)其实源码里面还是有一些代码不太懂,例如modCount变量,只知道是与线程安全相关,ArrayList是不安全的,可能与这个相关,在多线程下不建议使用;以后可以再回头看看仔细琢磨一些实现细节。

(2)ArrayList的实现中大量调用了 Arrays.copyof()和System.arraycopy()方法,这两个方法之前内部实现了解的不多,后来看源码仔细琢磨了一下,在上面有对它们的详细注解分析过程,相信看过之后应该会比较清晰,按我的理解实际上就是自我复制与自我覆盖。

(3)ArrayList是基于数组的存储结构,所以支持随机读取,是通过下标索引查找指定元素,但是在插入删除的时候效率很低,因为要大量的复制移动数组元素。

(4)ArrayList支持迭代,内部数组存储允许重复元素,特别也允许null的元素,也支持null元素的查找,从上面的源码分析看出内部是将null元素与普通元素分成两种情况分别遍历查找。

posted @ 2016-04-18 20:10  CfoolishbirdC  阅读(433)  评论(0编辑  收藏  举报