死磕JDK源码之ArrayList

ArrayList即动态数组,实现了动态的添加和减少元素

RandomAccess接口

标记接口,实现RandomAccess接口的类支持快速随机访问

Cloneable接口

没有实现Cloneable接口的类调用clone方法会抛出CloneNotSupportedException

Object提供的clone方法是浅度复制

Serializable接口

标记接口,实现Serializable接口的类可以被序列化

Iterable接口

实现Iterable接口的类支持for-each循环

AbstractCollection类

提供了Collection接口的骨干实现

contains

 1 public boolean contains(Object o) {
 2     Iterator<E> it = iterator();//调用自己的iterator()方法
 3     if (o == null) {//对o是null值进行判断(注意是等号)
 4         while (it.hasNext())
 5             if (it.next() == null)
 6                 return true;
 7     } else {//迭代器依次遍历,如果有和o一样的元素,返回true并跳出循环
 8         while (it.hasNext())
 9             /*
10             用元素所在类的equals()方法判断是否相等所以若存入
11             其中的元素是自定义对象则需要重写其equals()方法
12             */
13             if (o.equals(it.next()))
14                 return true;
15     }
16     return false;//遍历结束仍然没有与o相同的元素就返回false
17 }

toString

 1 public String toString() {
 2     Iterator<E> it = iterator();
 3     if (!it.hasNext())//对于空集合直接返回[]
 4         return "[]";
 5     StringBuilder sb = new StringBuilder();
 6     sb.append(‘[‘);
 7     for (;;) {
 8         E e = it.next();
 9         sb.append(e == this ? "(this Collection)" : e);//防止出现死循环
10         if (!it.hasNext())
11             return sb.append(‘]‘).toString();
12         sb.append(‘,‘).append(‘ ‘);
13     }
14 }

AbstractList类

提供了List接口的骨干实现

迭代器实现

  1 /*
  2 内部类实现了迭代器接口,实现了对于元素的遍历
  3 同时也解释了不能还没有调用next就remove和不能连续两次remove的原因:
  4 未调用next就remove,lastRet的值为-1,会抛出IllegalStateException
  5 而在第一次调用remove后,lastRet的值会置为-1,如果再次调用remove也会抛出异常
  6 */
  7 private class Itr implements Iterator<E> {
  8     int cursor = 0;//游标,表示下一个要访问的元素
  9     int lastRet = -1;//表示上一个访问的元素
 10     int expectedModCount = modCount;//对修改次数的期望值
 11     public boolean hasNext() {
 12         return cursor != size();
 13     }
 14     public E next() {
 15         checkForComodification();//检查遍历时集合有没有被修改过 fail-fast
 16         try {
 17         /*
 18             E next=get(cursor);
 19             lastRet=cursor++;
 20             return next;
 21         */
 22             int i = cursor;
 23             E next = get(i);//获取元素
 24             lastRet = i;//lastRet记录获取到的元素的索引
 25             cursor = i + 1;//准备获取下一个元素
 26             return next;
 27         } catch (IndexOutOfBoundsException e) {
 28             checkForComodification();
 29             throw new NoSuchElementException();
 30         }
 31     }
 32     public void remove() {
 33         if (lastRet < 0)
 34             throw new IllegalStateException();
 35         checkForComodification();
 36         try {
 37             //调用remove方法删除上一个访问的元素
 38             AbstractList.this.remove(lastRet);
 39             if (lastRet < cursor)
 40                 cursor--;
 41             /*
 42             删除后把lastRet置为-1,连续无间隔调用remove抛出
 43             IllegalStateException
 44             */
 45             lastRet = -1;
 46             expectedModCount = modCount;
 47         } catch (IndexOutOfBoundsException e) {
 48             throw new ConcurrentModificationException();
 49         }
 50     }
 51     final void checkForComodification() {
 52         if (modCount != expectedModCount)
 53             throw new ConcurrentModificationException();//并发修改异常
 54     }
 55 }
 56 /*
 57 支持在调用next或者previous后,添加元素
 58 调用next时,调用add,add方法会在cursor的位置上添加元素,并把cursor+1使得next的
 59 调用无法返回添加的元素
 60 调用previous时,调用add,add方法会在已经返回的元素位置处添加元素,并把cursor+1
 61 下次返回的会是cursor-1元素,即新添加的元素
 62 */
 63 private class ListItr extends Itr implements ListIterator<E> {
 64     ListItr(int index) {
 65         cursor = index;
 66     }
 67     public boolean hasPrevious() {
 68         return cursor != 0;
 69     }
 70     public E previous() {
 71         checkForComodification();
 72         try {
 73         /*
 74             E previous=get(--cursor);
 75             lastRet=cursor;
 76             return previous;
 77         */
 78             int i = cursor - 1;
 79             E previous = get(i);
 80             /*
 81             结束方法调用时,cursor停留在返回的元素的位置上,这点与next不同
 82             */
 83             lastRet = cursor = i;
 84             return previous;
 85         } catch (IndexOutOfBoundsException e) {
 86             checkForComodification();
 87             throw new NoSuchElementException();
 88         }
 89     }
 90     public int nextIndex() {
 91         return cursor;
 92     }
 93     public int previousIndex() {
 94         return cursor - 1;
 95     }
 96     public void set(E e) {//用指定元素替换next或者previous返回的最后一个元素
 97         if (lastRet < 0)
 98             throw new IllegalStateException();
 99         checkForComodification();
100         try {
101             AbstractList.this.set(lastRet, e);
102             expectedModCount = modCount;
103         } catch (IndexOutOfBoundsException ex) {
104             throw new ConcurrentModificationException();
105         }
106     }
107     public void add(E e) {//插入指定元素到next返回的下一个元素的前面(如果有的话)
108         checkForComodification();
109         try {
110             int i = cursor;
111             AbstractList.this.add(i, e);
112             lastRet = -1;
113             cursor = i + 1;//add方法使游标向前移动了一位
114             expectedModCount = modCount;
115         } catch (IndexOutOfBoundsException ex) {
116             throw new ConcurrentModificationException();
117         }
118     }
119 }

equals

 1 /*
 2 1.判断比较对象是否为自己本身,如果是,返回true
 3 2.判断比较对象是不是一个List,如果不是,返回false
 4 3.迭代比较两个list公共长度上的元素,发现有不相同的返回false
 5 4.两个list的长度不一样返回false
 6 为什么不在循环之前判断两个list的size()是否一样,不一样直接返回false,
 7 一样在进行循环判断比较所有元素是否相同?
 8 */
 9 public boolean equals(Object o) {//只有两个列表的元素以及顺序完全一样才返回true
10     if (o == this)
11         return true;
12     if (!(o instanceof List))//判断o这个引用真正指向的类
13         return false;
14     ListIterator<E> e1 = listIterator();
15     ListIterator<?> e2 = ((List<?>) o).listIterator();
16     while (e1.hasNext() && e2.hasNext()) {
17         E o1 = e1.next();
18         Object o2 = e2.next();
19         if (!(o1 == null ? o2 == null : o1.equals(o2)))
20             return false;
21     }
22     return !(e1.hasNext() || e2.hasNext());
23 }

ArrayList类

  1 package java.util;
  2 import java.util.function.Consumer;
  3 import java.util.function.Predicate;
  4 import java.util.function.UnaryOperator;
  5 public class ArrayList<E> extends AbstractList<E>
  6         implements List<E>, RandomAccess, Cloneable, java.io.Serializable
  7 {
  8     //Java的序列化机制是通过在运行时判断类的serialVersionUID来验证版本一致性的
  9     private static final long serialVersionUID = 8683452581122892189L;
 10     //默认初始化容量为10
 11     private static final int DEFAULT_CAPACITY = 10;
 12     //空的对象数组(用于new ArrayList(0)的初始化)
 13     private static final Object[] EMPTY_ELEMENTDATA = {};
 14     //用于new ArrayList()的初始化
 15     private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
 16     //真正保存数据的数组 transient表示不可序列化
 17     transient Object[] elementData;
 18     //ArrayList的实际元素数量
 19     private int size;
 20     //构造一个具有指定初始容量的空列表
 21     public ArrayList(int initialCapacity) {
 22         if (initialCapacity > 0) {
 23             this.elementData = new Object[initialCapacity];
 24         } else if (initialCapacity == 0) {
 25             this.elementData = EMPTY_ELEMENTDATA;
 26         } else {
 27             throw new IllegalArgumentException("Illegal Capacity: "+
 28                                                initialCapacity);
 29         }
 30     }
 31     //无参构造
 32     public ArrayList() {
 33         this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
 34     }
 35     //构造一个包含指定集合c元素的列表
 36     public ArrayList(Collection<? extends E> c) {
 37         elementData = c.toArray();
 38         if ((size = elementData.length) != 0) {
 39             //类型检查
 40             if (elementData.getClass() != Object[].class)
 41                 elementData = Arrays.copyOf(elementData, size, Object[].class);
 42         } else {
 43             this.elementData = EMPTY_ELEMENTDATA;
 44         }
 45     }
 46     //调整ArrayList的实际容量为size
 47     public void trimToSize() {
 48         //modCount记录修改次数+1
 49         modCount++;
 50         if (size < elementData.length) {
 51             elementData = (size == 0)
 52               ? EMPTY_ELEMENTDATA
 53               : Arrays.copyOf(elementData, size);
 54         }
 55     }
 56     public void ensureCapacity(int minCapacity) {
 57         int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
 58             ? 0 : DEFAULT_CAPACITY;
 59         if (minCapacity > minExpand) {
 60             ensureExplicitCapacity(minCapacity);
 61         }
 62     }
 63     private void ensureCapacityInternal(int minCapacity) {
 64         //如果实际存储数组是空数组 则最小需要容量就是默认容量
 65         if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
 66             minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
 67         }
 68         ensureExplicitCapacity(minCapacity);
 69     }
 70     private void ensureExplicitCapacity(int minCapacity) {
 71         modCount++;
 72         //如果数组(elementData)的长度小于最小需要的容量(minCapacity)就扩容
 73         if (minCapacity - elementData.length > 0)
 74             grow(minCapacity);
 75     }
 76     /*
 77     这个-8是为了减少出错的几率,避免一些机器内存溢出,最大长度依然是Integer.MAX_VALUE
 78     并不是Integer.MAX_VALUE-8(通过hugeCapacity()方法调整)
 79     */
 80     private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
 81     private void grow(int minCapacity) {
 82         int oldCapacity = elementData.length;
 83         //扩容为原来的1.5倍
 84         int newCapacity = oldCapacity + (oldCapacity >> 1);
 85         //如果扩容1.5倍仍小于最小需要容量(针对addAll方法),就直接扩容为最小需要容量
 86         if (newCapacity - minCapacity < 0)
 87             newCapacity = minCapacity;
 88         //若超出MAX_ARRAY_SIZE,调用hugeCapacity调整
 89         if (newCapacity - MAX_ARRAY_SIZE > 0)
 90             newCapacity = hugeCapacity(minCapacity);
 91         //复制元素
 92         elementData = Arrays.copyOf(elementData, newCapacity);
 93     }
 94     private static int hugeCapacity(int minCapacity) {
 95         //溢出
 96         if (minCapacity < 0)
 97             throw new OutOfMemoryError();
 98         return (minCapacity > MAX_ARRAY_SIZE) ?
 99             Integer.MAX_VALUE :
100             MAX_ARRAY_SIZE;
101     }
102     //返回元素数
103     public int size() {
104         return size;
105     }
106     //判断列表是否为空
107     public boolean isEmpty() {
108         return size == 0;
109     }
110     //判断是否包含指定元素
111     public boolean contains(Object o) {
112         return indexOf(o) >= 0;
113     }
114     //返回o第一次出现的索引,没有就返回-1
115     public int indexOf(Object o) {
116         //判断o是否为null,避免出现o.equals空指针异常
117         if (o == null) {
118             for (int i = 0; i < size; i++)
119                 if (elementData[i]==null)
120                     return i;
121         } else {
122             for (int i = 0; i < size; i++)
123                 if (o.equals(elementData[i]))
124                     return i;
125         }
126         return -1;
127     }
128     //返回o最后一次出现的索引,没有就返回-1
129     public int lastIndexOf(Object o) {
130         if (o == null) {
131             for (int i = size-1; i >= 0; i--)
132                 if (elementData[i]==null)
133                     return i;
134         } else {
135             for (int i = size-1; i >= 0; i--)
136                 if (o.equals(elementData[i]))
137                     return i;
138         }
139         return -1;
140     }
141     //浅度复制
142     public Object clone() {
143         try {
144             ArrayList<?> v = (ArrayList<?>) super.clone();
145             v.elementData = Arrays.copyOf(elementData, size);
146             v.modCount = 0;
147             return v;
148         } catch (CloneNotSupportedException e) {
149             //不会发生,因为已经实现了Cloneable接口
150             throw new InternalError(e);
151         }
152     }
153     //集合转换为数组
154     public Object[] toArray() {
155         return Arrays.copyOf(elementData, size);
156     }
157     //通过泛型约束返回指定类型的数组
158     @SuppressWarnings("unchecked")
159     public <T> T[] toArray(T[] a) {
160         if (a.length < size)
161             return (T[]) Arrays.copyOf(elementData, size, a.getClass());
162         /*
163         elementData:源数组 0:源数组要复制的起始位置
164         a:目的数组 0:目的数组要复制的起始位置
165         size:复制的长度
166         */
167         System.arraycopy(elementData, 0, a, 0, size);
168         if (a.length > size)
169             a[size] = null;
170         return a;
171     }
172     //返回数组指定位置元素(没有进行下标检查)
173     @SuppressWarnings("unchecked")
174     E elementData(int index) {
175         return (E) elementData[index];
176     }
177     //返回列表指定位置元素
178     public E get(int index) {
179         rangeCheck(index);
180         return elementData(index);
181     }
182     //用element替代指定位置上的元素
183     public E set(int index, E element) {
184         rangeCheck(index);
185         E oldValue = elementData(index);
186         elementData[index] = element;
187         //返回之前位于index上的元素
188         return oldValue;
189     }
190     //在列表尾部添加指定元素
191     public boolean add(E e) {
192         ensureCapacityInternal(size + 1);
193         elementData[size++] = e;
194         return true;
195     }
196     //把element添加到指定位置,当前元素和后续元素(如果有的话)向后移动
197     public void add(int index, E element) {
198         rangeCheckForAdd(index);
199         ensureCapacityInternal(size + 1);
200         //整体后移
201         System.arraycopy(elementData, index, elementData, index + 1,
202                          size - index);
203         elementData[index] = element;
204         size++;
205     }
206     //移除指定位置元素,向左移动后续元素(如果有的话)
207     public E remove(int index) {
208         rangeCheck(index);
209         modCount++;
210         E oldValue = elementData(index);
211         int numMoved = size - index - 1;
212         //numMoved=0,移除的是最后一个元素
213         if (numMoved > 0)
214             System.arraycopy(elementData, index+1, elementData, index,
215                              numMoved);
216         //for GC
217         elementData[--size] = null;
218         //返回从列表中移除的元素
219         return oldValue;
220     }
221     //如果集合中有o,则删除第一次出现的并返回true 如果没有,集合不变并返回false
222     public boolean remove(Object o) {
223         if (o == null) {
224             for (int index = 0; index < size; index++)
225                 if (elementData[index] == null) {
226                     fastRemove(index);
227                     return true;
228                 }
229         } else {
230             for (int index = 0; index < size; index++)
231                 if (o.equals(elementData[index])) {
232                     fastRemove(index);
233                     return true;
234                 }
235         }
236         return false;
237     }
238     //把重复的代码移到一个方法里面
239     private void fastRemove(int index) {
240         modCount++;
241         int numMoved = size - index - 1;
242         if (numMoved > 0)
243             System.arraycopy(elementData, index+1, elementData, index,
244                              numMoved);
245         //for GC
246         elementData[--size] = null;
247     }
248     //移除列表所有元素
249     public void clear() {
250         modCount++;
251         for (int i = 0; i < size; i++)
252             elementData[i] = null;
253         size = 0;
254     }
255     //添加集合c中的所有元素到列表尾部
256     public boolean addAll(Collection<? extends E> c) {
257         Object[] a = c.toArray();
258         int numNew = a.length;
259         ensureCapacityInternal(size + numNew);
260         System.arraycopy(a, 0, elementData, size, numNew);
261         size += numNew;
262         return numNew != 0;
263     }
264     //从指定的位置开始,移动c中的所有元素到列表中,当前元素和后续元素(如果有的话)向右移动
265     public boolean addAll(int index, Collection<? extends E> c) {
266         rangeCheckForAdd(index);
267         Object[] a = c.toArray();
268         int numNew = a.length;
269         ensureCapacityInternal(size + numNew);
270         int numMoved = size - index;
271         if (numMoved > 0)
272             System.arraycopy(elementData, index, elementData, index + numNew,
273                              numMoved);
274         System.arraycopy(a, 0, elementData, index, numNew);
275         size += numNew;
276         return numNew != 0;
277     }
278     //移除列表中索引在fromIndex(包括)和toIndex(不包括)之间的所有元素
279     protected void removeRange(int fromIndex, int toIndex) {
280         modCount++;
281         int numMoved = size - toIndex;
282         System.arraycopy(elementData, toIndex, elementData, fromIndex,
283                          numMoved);
284         //for GC
285         int newSize = size - (toIndex-fromIndex);
286         for (int i = newSize; i < size; i++) {
287             elementData[i] = null;
288         }
289         size = newSize;
290     }
291     //边界检查
292     private void rangeCheck(int index) {
293         if (index >= size)
294             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
295     }
296     //add和addAll中的边界检查
297     private void rangeCheckForAdd(int index) {
298         if (index > size || index < 0)
299             throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
300     }
301     //错误处理
302     private String outOfBoundsMsg(int index) {
303         return "Index: "+index+", Size: "+size;
304     }
305     public boolean removeAll(Collection<?> c) {
306         //传入的参数不为null,返回参数本身,为null,抛出一个空指针异常
307         Objects.requireNonNull(c);
308         return batchRemove(c, false);
309     }
310     public boolean retainAll(Collection<?> c) {
311         Objects.requireNonNull(c);
312         return batchRemove(c, true);
313     }
314     //beautiful code!
315     private boolean batchRemove(Collection<?> c, boolean complement) {
316         final Object[] elementData = this.elementData;
317         int r = 0, w = 0;
318         boolean modified = false;
319         try {
320             for (; r < size; r++)
321                 if (c.contains(elementData[r]) == complement)
322                     elementData[w++] = elementData[r];
323         } finally {
324             //发生了异常,直接把r后面的复制到w后面
325             if (r != size) {
326                 System.arraycopy(elementData, r,
327                                  elementData, w,
328                                  size - r);
329                 w += size - r;
330             }
331             if (w != size) {
332                 //for GC
333                 for (int i = w; i < size; i++)
334                     elementData[i] = null;
335                 modCount += size - w;
336                 size = w;
337                 modified = true;
338             }
339         }
340         return modified;
341     }
342     private void writeObject(java.io.ObjectOutputStream s)
343         throws java.io.IOException{
344         int expectedModCount = modCount;
345         s.defaultWriteObject();
346         s.writeInt(size);
347         for (int i=0; i<size; i++) {
348             s.writeObject(elementData[i]);
349         }
350         if (modCount != expectedModCount) {
351             throw new ConcurrentModificationException();
352         }
353     }
354     private void readObject(java.io.ObjectInputStream s)
355         throws java.io.IOException, ClassNotFoundException {
356         elementData = EMPTY_ELEMENTDATA;
357         s.defaultReadObject();
358         s.readInt();
359         if (size > 0) {
360             ensureCapacityInternal(size);
361             Object[] a = elementData;
362             for (int i=0; i<size; i++) {
363                 a[i] = s.readObject();
364             }
365         }
366     }
367     //得到一个指定位置的迭代器
368     public ListIterator<E> listIterator(int index) {
369         if (index < 0 || index > size)
370             throw new IndexOutOfBoundsException("Index: "+index);
371         return new ListItr(index);
372     }
373     public ListIterator<E> listIterator() {
374         return new ListItr(0);
375     }
376     public Iterator<E> iterator() {
377         return new Itr();
378     }
379     //AbstractList中Itr的优化版本
380     private class Itr implements Iterator<E> {
381         //下一个返回元素的索引
382         int cursor;
383         //上一个返回元素的索引,如果没有,置为-1
384         int lastRet = -1;
385         int expectedModCount = modCount;
386         public boolean hasNext() {
387             return cursor != size;
388         }
389         @SuppressWarnings("unchecked")
390         public E next() {
391             checkForComodification();
392             int i = cursor;
393             if (i >= size)
394                 throw new NoSuchElementException();
395             Object[] elementData = ArrayList.this.elementData;
396             if (i >= elementData.length)
397                 throw new ConcurrentModificationException();
398             cursor = i + 1;
399             return (E) elementData[lastRet = i];
400         }
401         public void remove() {
402             if (lastRet < 0)
403                 throw new IllegalStateException();
404             checkForComodification();
405             try {
406                 ArrayList.this.remove(lastRet);
407                 cursor = lastRet;
408                 lastRet = -1;
409                 expectedModCount = modCount;
410             } catch (IndexOutOfBoundsException ex) {
411                 throw new ConcurrentModificationException();
412             }
413         }
414         @Override
415         @SuppressWarnings("unchecked")
416         public void forEachRemaining(Consumer<? super E> consumer) {
417             Objects.requireNonNull(consumer);
418             final int size = ArrayList.this.size;
419             int i = cursor;
420             if (i >= size) {
421                 return;
422             }
423             final Object[] elementData = ArrayList.this.elementData;
424             if (i >= elementData.length) {
425                 throw new ConcurrentModificationException();
426             }
427             while (i != size && modCount == expectedModCount) {
428                 consumer.accept((E) elementData[i++]);
429             }
430             cursor = i;
431             lastRet = i - 1;
432             checkForComodification();
433         }
434         final void checkForComodification() {
435             if (modCount != expectedModCount)
436                 throw new ConcurrentModificationException();
437         }
438     }
439     //AbstractList中ListItr的优化版本
440     private class ListItr extends Itr implements ListIterator<E> {
441         ListItr(int index) {
442             super();
443             cursor = index;
444         }
445         public boolean hasPrevious() {
446             return cursor != 0;
447         }
448         public int nextIndex() {
449             return cursor;
450         }
451         public int previousIndex() {
452             return cursor - 1;
453         }
454         @SuppressWarnings("unchecked")
455         public E previous() {
456             checkForComodification();
457             int i = cursor - 1;
458             if (i < 0)
459                 throw new NoSuchElementException();
460             Object[] elementData = ArrayList.this.elementData;
461             if (i >= elementData.length)
462                 throw new ConcurrentModificationException();
463             cursor = i;
464             return (E) elementData[lastRet = i];
465         }
466         public void set(E e) {
467             if (lastRet < 0)
468                 throw new IllegalStateException();
469             checkForComodification();
470             try {
471                 ArrayList.this.set(lastRet, e);
472             } catch (IndexOutOfBoundsException ex) {
473                 throw new ConcurrentModificationException();
474             }
475         }
476         public void add(E e) {
477             checkForComodification();
478             try {
479                 int i = cursor;
480                 ArrayList.this.add(i, e);
481                 cursor = i + 1;
482                 lastRet = -1;
483                 expectedModCount = modCount;
484             } catch (IndexOutOfBoundsException ex) {
485                 throw new ConcurrentModificationException();
486             }
487         }
488     }
489     public List<E> subList(int fromIndex, int toIndex) {
490         subListRangeCheck(fromIndex, toIndex, size);
491         return new SubList(this, 0, fromIndex, toIndex);
492     }
493     static void subListRangeCheck(int fromIndex, int toIndex, int size) {
494         if (fromIndex < 0)
495             throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
496         if (toIndex > size)
497             throw new IndexOutOfBoundsException("toIndex = " + toIndex);
498         if (fromIndex > toIndex)
499             throw new IllegalArgumentException("fromIndex(" + fromIndex +
500                                                ") > toIndex(" + toIndex + ")");
501     }
502     private class SubList extends AbstractList<E> implements RandomAccess {
503         private final AbstractList<E> parent;
504         private final int parentOffset;
505         private final int offset;
506         int size;
507         SubList(AbstractList<E> parent,
508                 int offset, int fromIndex, int toIndex) {
509             this.parent = parent;
510             this.parentOffset = fromIndex;
511             this.offset = offset + fromIndex;
512             this.size = toIndex - fromIndex;
513             this.modCount = ArrayList.this.modCount;
514         }
515         public E set(int index, E e) {
516             rangeCheck(index);
517             checkForComodification();
518             E oldValue = ArrayList.this.elementData(offset + index);
519             ArrayList.this.elementData[offset + index] = e;
520             return oldValue;
521         }
522         public E get(int index) {
523             rangeCheck(index);
524             checkForComodification();
525             return ArrayList.this.elementData(offset + index);
526         }
527         public int size() {
528             checkForComodification();
529             return this.size;
530         }
531         public void add(int index, E e) {
532             rangeCheckForAdd(index);
533             checkForComodification();
534             parent.add(parentOffset + index, e);
535             this.modCount = parent.modCount;
536             this.size++;
537         }
538         public E remove(int index) {
539             rangeCheck(index);
540             checkForComodification();
541             E result = parent.remove(parentOffset + index);
542             this.modCount = parent.modCount;
543             this.size--;
544             return result;
545         }
546         protected void removeRange(int fromIndex, int toIndex) {
547             checkForComodification();
548             parent.removeRange(parentOffset + fromIndex,
549                                parentOffset + toIndex);
550             this.modCount = parent.modCount;
551             this.size -= toIndex - fromIndex;
552         }
553         public boolean addAll(Collection<? extends E> c) {
554             return addAll(this.size, c);
555         }
556         public boolean addAll(int index, Collection<? extends E> c) {
557             rangeCheckForAdd(index);
558             int cSize = c.size();
559             if (cSize==0)
560                 return false;
561             checkForComodification();
562             parent.addAll(parentOffset + index, c);
563             this.modCount = parent.modCount;
564             this.size += cSize;
565             return true;
566         }
567         public Iterator<E> iterator() {
568             return listIterator();
569         }
570         public ListIterator<E> listIterator(final int index) {
571             checkForComodification();
572             rangeCheckForAdd(index);
573             final int offset = this.offset;
574             return new ListIterator<E>() {
575                 int cursor = index;
576                 int lastRet = -1;
577                 int expectedModCount = ArrayList.this.modCount;
578                 public boolean hasNext() {
579                     return cursor != SubList.this.size;
580                 }
581                 @SuppressWarnings("unchecked")
582                 public E next() {
583                     checkForComodification();
584                     int i = cursor;
585                     if (i >= SubList.this.size)
586                         throw new NoSuchElementException();
587                     Object[] elementData = ArrayList.this.elementData;
588                     if (offset + i >= elementData.length)
589                         throw new ConcurrentModificationException();
590                     cursor = i + 1;
591                     return (E) elementData[offset + (lastRet = i)];
592                 }
593                 public boolean hasPrevious() {
594                     return cursor != 0;
595                 }
596                 @SuppressWarnings("unchecked")
597                 public E previous() {
598                     checkForComodification();
599                     int i = cursor - 1;
600                     if (i < 0)
601                         throw new NoSuchElementException();
602                     Object[] elementData = ArrayList.this.elementData;
603                     if (offset + i >= elementData.length)
604                         throw new ConcurrentModificationException();
605                     cursor = i;
606                     return (E) elementData[offset + (lastRet = i)];
607                 }
608                 @SuppressWarnings("unchecked")
609                 public void forEachRemaining(Consumer<? super E> consumer) {
610                     Objects.requireNonNull(consumer);
611                     final int size = SubList.this.size;
612                     int i = cursor;
613                     if (i >= size) {
614                         return;
615                     }
616                     final Object[] elementData = ArrayList.this.elementData;
617                     if (offset + i >= elementData.length) {
618                         throw new ConcurrentModificationException();
619                     }
620                     while (i != size && modCount == expectedModCount) {
621                         consumer.accept((E) elementData[offset + (i++)]);
622                     }
623                     lastRet = cursor = i;
624                     checkForComodification();
625                 }
626                 public int nextIndex() {
627                     return cursor;
628                 }
629                 public int previousIndex() {
630                     return cursor - 1;
631                 }
632                 public void remove() {
633                     if (lastRet < 0)
634                         throw new IllegalStateException();
635                     checkForComodification();
636                     try {
637                         SubList.this.remove(lastRet);
638                         cursor = lastRet;
639                         lastRet = -1;
640                         expectedModCount = ArrayList.this.modCount;
641                     } catch (IndexOutOfBoundsException ex) {
642                         throw new ConcurrentModificationException();
643                     }
644                 }
645                 public void set(E e) {
646                     if (lastRet < 0)
647                         throw new IllegalStateException();
648                     checkForComodification();
649                     try {
650                         ArrayList.this.set(offset + lastRet, e);
651                     } catch (IndexOutOfBoundsException ex) {
652                         throw new ConcurrentModificationException();
653                     }
654                 }
655                 public void add(E e) {
656                     checkForComodification();
657                     try {
658                         int i = cursor;
659                         SubList.this.add(i, e);
660                         cursor = i + 1;
661                         lastRet = -1;
662                         expectedModCount = ArrayList.this.modCount;
663                     } catch (IndexOutOfBoundsException ex) {
664                         throw new ConcurrentModificationException();
665                     }
666                 }
667                 final void checkForComodification() {
668                     if (expectedModCount != ArrayList.this.modCount)
669                         throw new ConcurrentModificationException();
670                 }
671             };
672         }
673         public List<E> subList(int fromIndex, int toIndex) {
674             subListRangeCheck(fromIndex, toIndex, size);
675             return new SubList(this, offset, fromIndex, toIndex);
676         }
677         private void rangeCheck(int index) {
678             if (index < 0 || index >= this.size)
679                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
680         }
681         private void rangeCheckForAdd(int index) {
682             if (index < 0 || index > this.size)
683                 throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
684         }
685         private String outOfBoundsMsg(int index) {
686             return "Index: "+index+", Size: "+this.size;
687         }
688         private void checkForComodification() {
689             if (ArrayList.this.modCount != this.modCount)
690                 throw new ConcurrentModificationException();
691         }
692         public Spliterator<E> spliterator() {
693             checkForComodification();
694             return new ArrayListSpliterator<E>(ArrayList.this, offset,
695                                                offset + this.size, this.modCount);
696         }
697     }
698     @Override
699     public void forEach(Consumer<? super E> action) {
700         Objects.requireNonNull(action);
701         final int expectedModCount = modCount;
702         @SuppressWarnings("unchecked")
703         final E[] elementData = (E[]) this.elementData;
704         final int size = this.size;
705         for (int i=0; modCount == expectedModCount && i < size; i++) {
706             action.accept(elementData[i]);
707         }
708         if (modCount != expectedModCount) {
709             throw new ConcurrentModificationException();
710         }
711     }
712     @Override
713     public Spliterator<E> spliterator() {
714         return new ArrayListSpliterator<>(this, 0, -1, 0);
715     }
716     static final class ArrayListSpliterator<E> implements Spliterator<E> {
717         private final ArrayList<E> list;
718         private int index;
719         private int fence;
720         private int expectedModCount;
721         ArrayListSpliterator(ArrayList<E> list, int origin, int fence,
722                              int expectedModCount) {
723             this.list = list;
724             this.index = origin;
725             this.fence = fence;
726             this.expectedModCount = expectedModCount;
727         }
728         private int getFence() {
729             int hi;
730             ArrayList<E> lst;
731             if ((hi = fence) < 0) {
732                 if ((lst = list) == null)
733                     hi = fence = 0;
734                 else {
735                     expectedModCount = lst.modCount;
736                     hi = fence = lst.size;
737                 }
738             }
739             return hi;
740         }
741         public ArrayListSpliterator<E> trySplit() {
742             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
743             return (lo >= mid) ? null :
744                 new ArrayListSpliterator<E>(list, lo, index = mid,
745                                             expectedModCount);
746         }
747         public boolean tryAdvance(Consumer<? super E> action) {
748             if (action == null)
749                 throw new NullPointerException();
750             int hi = getFence(), i = index;
751             if (i < hi) {
752                 index = i + 1;
753                 @SuppressWarnings("unchecked") E e = (E)list.elementData[i];
754                 action.accept(e);
755                 if (list.modCount != expectedModCount)
756                     throw new ConcurrentModificationException();
757                 return true;
758             }
759             return false;
760         }
761         public void forEachRemaining(Consumer<? super E> action) {
762             int i, hi, mc;
763             ArrayList<E> lst; Object[] a;
764             if (action == null)
765                 throw new NullPointerException();
766             if ((lst = list) != null && (a = lst.elementData) != null) {
767                 if ((hi = fence) < 0) {
768                     mc = lst.modCount;
769                     hi = lst.size;
770                 }
771                 else
772                     mc = expectedModCount;
773                 if ((i = index) >= 0 && (index = hi) <= a.length) {
774                     for (; i < hi; ++i) {
775                         @SuppressWarnings("unchecked") E e = (E) a[i];
776                         action.accept(e);
777                     }
778                     if (lst.modCount == mc)
779                         return;
780                 }
781             }
782             throw new ConcurrentModificationException();
783         }
784         public long estimateSize() {
785             return (long) (getFence() - index);
786         }
787         public int characteristics() {
788             return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;
789         }
790     }
791     @Override
792     public boolean removeIf(Predicate<? super E> filter) {
793         Objects.requireNonNull(filter);
794         int removeCount = 0;
795         final BitSet removeSet = new BitSet(size);
796         final int expectedModCount = modCount;
797         final int size = this.size;
798         for (int i=0; modCount == expectedModCount && i < size; i++) {
799             @SuppressWarnings("unchecked")
800             final E element = (E) elementData[i];
801             if (filter.test(element)) {
802                 removeSet.set(i);
803                 removeCount++;
804             }
805         }
806         if (modCount != expectedModCount) {
807             throw new ConcurrentModificationException();
808         }
809         final boolean anyToRemove = removeCount > 0;
810         if (anyToRemove) {
811             final int newSize = size - removeCount;
812             for (int i=0, j=0; (i < size) && (j < newSize); i++, j++) {
813                 i = removeSet.nextClearBit(i);
814                 elementData[j] = elementData[i];
815             }
816             for (int k=newSize; k < size; k++) {
817                 elementData[k] = null;
818             }
819             this.size = newSize;
820             if (modCount != expectedModCount) {
821                 throw new ConcurrentModificationException();
822             }
823             modCount++;
824         }
825         return anyToRemove;
826     }
827     @Override
828     @SuppressWarnings("unchecked")
829     public void replaceAll(UnaryOperator<E> operator) {
830         Objects.requireNonNull(operator);
831         final int expectedModCount = modCount;
832         final int size = this.size;
833         for (int i=0; modCount == expectedModCount && i < size; i++) {
834             elementData[i] = operator.apply((E) elementData[i]);
835         }
836         if (modCount != expectedModCount) {
837             throw new ConcurrentModificationException();
838         }
839         modCount++;
840     }
841     @Override
842     @SuppressWarnings("unchecked")
843     public void sort(Comparator<? super E> c) {
844         final int expectedModCount = modCount;
845         Arrays.sort((E[]) elementData, 0, size, c);
846         if (modCount != expectedModCount) {
847             throw new ConcurrentModificationException();
848         }
849         modCount++;
850     }
851 }

小结

1. ArrayList中的remove方法是移除第一次出现的元素,而不是所有的元素
2. 对数组操作的System.arraycopy()并没有创建新的数组,只是在原数组上移动元素,而Arrays.copyOf()操作返回了一个新的数组,对原数组没有影响
3. batchRemove()方法写的很nice,在方法参数中置入boolean变量来合并处理几种类似的情况,可有效减少代码冗余
4. 有必要对ArrayList按预估容量显示初始化,而不是仅仅new ArrayList(),频繁的扩容很影响性能
5. ArrayList中的Itr ListItr subList分析待续…

原文地址:https://www.cnblogs.com/sakura1027/p/8901659.html

时间: 2024-10-05 05:04:50

死磕JDK源码之ArrayList的相关文章

死磕JDK源码之LinkedList

LinkedList LinkedList底层是基于双向链表实现的 内置插入删除方法 linkFirst & linkLast unlinkFirst & unlinkLast linkBefore unlink 源码分析 1 package java.util; 2 import java.util.function.Consumer; 3 public class LinkedList<E> extends AbstractSequentialList<E> i

死磕Tomcat7源码之二:web组件初始化

经过死磕Tomcat7源码之一:解析web.xml,已经知道webapp的配置信息是如何解析到内存中.接下来,就是如何将对应的组件对象初始化化.分析所有的组件初始化过程,根本不可能.本文重点针对阐明3个主要组件的初始化过程,分别是:servlet,listener,filter.通过本文,你可以掌握以下知识点 了解组件初始化调用序列 组件servlet,listener,filter组件的初始化顺序 listener的初始化过程 servlet的初始化过程 filter的初始化过程 1.组件初始

JDK源码学习----ArrayList

                                                                         JDK源码学习----ArrayList 1.ArrayList简介 ArrayList是基于Object[] 数组的,也就是我们常说的动态数组.它能很方便的实现数组的增加删除等操作. public class ArrayList<E> extends AbstractList<E> implements List<E>, R

由JDK源码学习ArrayList

ArrayList是实现了List接口的动态数组.与java中的数组相比,它的容量能动态增长.ArrayList的三大特点: ① 底层采用数组结构 ② 有序 ③ 非同步 下面我们从ArrayList的增加元素.获取元素.删除元素三个方面来学习ArrayList. ArrayList添加元素 因为ArrayList是采用数组实现的,其源代码比较简单.首先我们来看ArrayList的add(E e).以下代码版本是jdk7. public boolean add(E e) { // 检查数组容量 e

从JDK源码学习Arraylist

从今天开始从源码去学习一些Java的常用数据结构,打好基础:) Arraylist源码阅读: jdk版本:1.8.0 首先看其构造方法: 构造方法一: 第一种支持初始化容量大小,其中声明一个对象数组,赋值给this.elementdata 构造方法二: 第二种无参构造函数,即不指定初始容量大小,则默认赋值this.elementdata为一个空的对象数组,但是由注释可以看到其无参构造实际上初始容量为10 在elementData的注释中也说了该变量是实际存储Arrylist数据的存储结构,任何空

JDK源码分析-ArrayList分析

花了两个晚上的时间研究了一下ArrayList的源码, ArrayList 继承自AbstractList 并且实现了List, RandomAccess, Cloneable, Serializable 通过实现这三个接口 就具备了他们的功能 RandomAccess 用来表明其支持快速(通常是固定时间)随机访问 Cloneable可以克隆对象 Serializable 对象序列化就是把一个对象变为二进制的数据流的一种方法,通过对象序列化可以方便地实现对象的传输和存储,Serializable

【死磕jeestie源码】类型后面三个点(String...)和数组(String[])的区别

类型后面三个点(String...),是从Java 5开始,Java语言对方法参数支持一种新写法,叫可变长度参数列表,其语法就是类型后跟...,表示此处接受的参数为0到多个Object类型的对象,或者是一个Object[]. 例如我们有一个方法叫做test(String...strings),那么你还可以写方法test(),但你不能写test(String[] strings),这样会出编译错误,系统提示出现重复的方法. 在使用的时候,对于test(String...strings),你可以直接

死磕itchat源码--config.py

itchat的配置文件,源码: import os, platform # 版本及微信的url,二维码等 VERSION = '1.3.10' BASE_URL = 'https://login.weixin.qq.com' OS = platform.system() # Windows, Linux, Darwin DIR = os.getcwd() DEFAULT_QR = 'QR.png' TIMEOUT = (10, 60) # 代理配置 USER_AGENT = 'Mozilla/5

死磕itchat源码--core.py

core.py文件中的Core类定义了itchat的所有接口.且,仅仅是定义了接口,全部在component包中实现重构.其用法如下表述: 缺省 源码如下: # -*- encoding: utf-8 -*- import logging import requests from . import config, storage, utils, log from .components import load_components class Core(object): """