死磕JDK源码之ArrayList

Posted sakura1027

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了死磕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         死磕JDK源码之Thread

死磕 java集合之CopyOnWriteArrayList源码分析

死磕 java集合之CopyOnWriteArrayList源码分析

死磕 java集合之LinkedList源码分析

死磕 java集合之LinkedList源码分析

JDK1.8源码之ArrayList