类图
官方文档
ArrayList成员变量
ArrayList构造函数
ArrayList内部类
ArrayList成员方法
ArrayList成员方法源码解析
1. public ArrayList(int initialCapacity)
带参构造方法
public ArrayList(int initialCapacity) {
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+
initialCapacity);
}
}
源码解析:
- 功能: 带参数构造函数,初始化数组的容量
- 源码思路:
- (1)判断传递进来的容量,容量值与0相比较,如果大于0,new一个Object类型的数组,将其赋给elementData
- (2)如果容量值等于0,说明想要初始化的数组容量为空,那直接将EMPTY_ELEMENTDATA赋给elementData
- (3)如果容量值小于0,则不符合题意,抛出异常
2. public ArrayList()
空参构造方法
public ArrayList() {
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
源码解析:
- 功能:初始化数组元素,因为没有参数,所以默认数组的元素个数为0,将DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋给elementData
3. public ArrayList(Collection<? extends E> c)
方法
public ArrayList(Collection<? extends E> c) {
elementData = c.toArray();
if ((size = elementData.length) != 0) {
// c.toArray might (incorrectly) not return Object[] (see 6260652)
if (elementData.getClass() != Object[].class)
elementData = Arrays.copyOf(elementData, size, Object[].class);
} else {
// replace with empty array.
this.elementData = EMPTY_ELEMENTDATA;
}
}
源码解析:
- 功能: 初始化ArrayList元素,使用已知传递进来的元素进行初始化
- 源码思路:
- (1)调用Collection类型形式参数c的toArray方法,将集合元素编程数组元素,存储在elementData中
- (2)将elementData数组的长度值赋给size,判断如果size的值不等于0,则再继续判断如果elementData数组的class值是否等于Object类型的数组的class,如果不相等,使用Arrays类的copyOf方法,给elementData数组赋初值
- (3)如果传递进来的集合元素为null,则将elementData数组赋为初始空数组EMPTY_ELEMENTDATA
4. public void trimToSize()
方法
public void trimToSize() {
modCount++;
if (size < elementData.length) {
elementData = (size == 0)
? EMPTY_ELEMENTDATA
: Arrays.copyOf(elementData, size);
}
}
源码解析:
- 功能:修整此ArrayList实例的是列表的当前大小的容量。ArrayList所说没有用的值并不是null,而是ArrayList每次增长会申请多一点的空间,增长1.5倍+1,而不是两倍这样就会出现当size() = 1000的时候,ArrayList已经申请了1200空间的情况trimToSize 的作用只是去掉预留元素位置,就是删除多余的200,改为只申请1000,内存紧张的时候会用到
- 源码思路:
- 修改的方式是通过调用Arrays类的copyOf方法
5. public void ensureCapacity(int minCapacity)
方法
public void ensureCapacity(int minCapacity) {
int minExpand = (elementData != DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
? 0 : DEFAULT_CAPACITY;
if (minCapacity > minExpand) {
ensureExplicitCapacity(minCapacity);
}
}
源码解析:
- 功能: 我们在使用ArrayList时,经常要对ArrayList进行扩容
- 源码思路:
- (1)任何一个ArrayList对象都有一个capacity属性,用来指示该ArrayList的最小容量,即数组的“容纳能力”,我们知道ArrayList的内部是采用数组来存储元素的,由于Java数组是定长的,所以这个数组的大小一定是固定的,这个大小就是capacity。我们可以肯定capacity一定是大于或者等于ArrayList的size,那么当size不断增加到了要超过capacity的时候,ArrayList就不得不重新创建新的capacity来容纳更多的元素,这时需要首先建立一个更长的数组,将原来的数组中的元素赋值到新数组中,再删除原来的数组。因此当ArrayList越来越大时,这种操作的消耗也就越来越大。
- (2)为了减少这种不必要的重建capacity操作,当我们能肯定ArrayList大致有多大时,我们可以先让ArrayList把capacity设为我们期望的大小,以避免多余的数组重建
- (3)建设ArrayList自动把capacity设为10,每次重建时将长度递增原来的三分之二,那么当我们需要大约存储50个元素到ArrayList中时,就会大约需要重建数组4次,分别在增加第11、第17、第26、第39个元素的时候进行。如果我们一开始就让ArrayList的capacity为50,那么不需要任何数组重建就能完成所有插入操作了。
- (4)Java允许我们在构造ArrayList的同时指定capacity,如new ArrayList(50),也允许在以后将它设得更大,而增大capacity就是使用ensureCapacity()方法。注意:capacity只能比原来的更大,不能比原来的更小,否则Java会忽略该操作。ArrayList的初始默认capacity为10,所以给capacity指定小于10的整数毫无意义。
- (5)ArrayList的size一定小于等于capacity,而且更重要的是,访问超过size的位置将抛出异常,尽管这个位置可能没有超过capacity。ensureCapacity()只可能增加capacity,而不会对size有任何影响。要增加size,只能用add()方法
6. private static int calculateCapacity(Object[] elementData, int minCapacity)
方法
private static int calculateCapacity(Object[] elementData, int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
return minCapacity;
}
源码解析:
- 功能:计算最小容量
- 源码思路:
- (1)判断如果elementData的值等于默认空数组的值,那么返回DEFAULT_CAPACITY和minCapacity中的最大值
- (2)如果elementData的值不等于默认空数组的值,则返回minCapacity值
7. private void ensureCapacityInternal(int minCapacity)
方法
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
源码解析:
- 功能:扩容入口方法
8. private void ensureExplicitCapacity(int minCapacity)
方法
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
源码解析:
- 功能:判断是否需要扩容
- 源码思路:
- 首先要更改modCount的值
- 如果最小需要空间比当前的elementData的长度大,则需要扩容,调用grow扩容方法,将minCapacity传递进去
9. private void grow(int minCapacity)
方法
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
源码解析:
- 功能:动态扩容
- 源码思路:
- (1)定义一个变量oldCapacity,其值等于ArrayList中elementData数组的长度
- (2)定义一个变量newCapacity,其值等于ArrayList中elementData数组长度的1.5倍
- (3)如果新数组的容量小于预留的数组空间,就可以直接使用这个长度新建数组
- (4)如果新数组的容量大于预留的数组空间,就将预留数组长度设置为需要的长度
- (5)MAX_ARRAY_SIZE 值等于Java中int的最大值。下面要判断有没有超过最大限制,如果没有,就执行下一步,如果超过最大限制,需要修改最大限制
- (6)调用Arrays的copyOf方法将elementData数组指向新的内存空间newCapacity,并将elementData数组中的值传递到新的内存空间中
10. private static int hugeCapacity(int minCapacity)
方法
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
源码解析:
- 功能:数组能够容纳的最大数据元素个数
- 源码思路:
- (1)如果数组能够容纳数据的能力小于0,说明minCapacity是错误的,因此抛出异常
- (2)如果minCapacity的值大于数组的size,则返回整数的最大值,否则返回数组的size
11. public int size()
方法
public int size() {
return size;
}
源码解析:
-功能:获取数组的size大小
12. public boolean isEmpty()
方法
public boolean isEmpty() {
return size == 0;
}
源码解析:
- 功能:判断数组中是否有元素
- 源码思路:
- 判断size的值是否为0
13. public boolean contains(Object o)
方法
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
源码解析:
- 功能:判断一个元素是否存在在数组中
- 源码思路:
- 通过调用indexOf方法来实现该功能
14. public int indexOf(Object o)
方法
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
源码解析:
- 功能:从左到右判断元素是否在数组中,如果在,则返回元素的下标,如果不在返回-1,直到找到或者到数组末尾为止
- 源码思路:
- 分两种情况进行判断,一种是元素是null,另一种是元素非空
- 当元素是null时,通过for循环遍历数组,当找到数组中元素==null则返回元素下标i
- 当元素是非空时,通过for循环遍历数组,通过equals方法来判断数组中是否存在想找的元素
15. public int lastIndexOf(Object o)
方法
public int lastIndexOf(Object o) {
if (o == null) {
for (int i = size-1; i >= 0; i--)
if (elementData[i]==null)
return i;
} else {
for (int i = size-1; i >= 0; i--)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
源码解析:
- 功能:从右往左判断是否有元素o,如果有则返回元素的下标,否则返回-1
- 源码思路:
- 与
indexOf
方法相反
- 与
16. public Object clone()
方法
public Object clone() { try { ArrayList<?> v = (ArrayList<?>) super.clone(); v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; } catch (CloneNotSupportedException e) { // this shouldn't happen, since we are Cloneable throw new InternalError(e); } }
源码解析:
- 功能:克隆
- 源码思路:
- (1)调用super.clone
- (2)将elementData中的元素克隆到新的elementData中
- (3)将新的集合的modCount 值设置为0
17. public Object[] toArray()
方法
public Object[] toArray() {
return Arrays.copyOf(elementData, size);
}
源码解析:
- 功能:将集合元素变为Object类型的数组返回
- 源码思路:
- 实现的方式是通过Arrays类的copyOf方法实现
18. public <T> T[] toArray(T[] a)
方法
public <T> T[] toArray(T[] a) {
if (a.length < size)
return (T[]) Arrays.copyOf(elementData, size, a.getClass());
System.arraycopy(elementData, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
源码解析:
- 功能:将集合中的元素转换为泛型类型的数组,存储在参数中返回
- 源码思路:
- (1)如果返回的参数a的数组长度小于集合的size,说明参数不能够存储下集合中的元素,直接通过调用Arrays类的copyOf方法,将调用结果返回
- (2)如果参数a的数组长度大于集合的size,说明参数能够存储下集合中的元素,调用System类的arraycopy方法将集合中的元素放在数组中,因为a的存储空间有多余的部分,需要最后将下标为size的元素置为null,最后返回a
19. E elementData(int index)
方法
E elementData(int index) {
return (E) elementData[index];
}
源码解析:
- 功能:返回elementData数组下标为index的元素值,get方法的基础方法
- 源码思路:
- 因为elementData本身是数组,所以想返回下标index的元素值,直接利用数组的elementData[index]即可
20. public E get(int index)
方法
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
源码解析:
- 功能:返回集合中下标为index的元素
- 源码思路:
- 首先调用rangeCheck方法判断index是否符合题意
- 返回调用elementData方法的结果
21. public E set(int index, E element)
方法
public E set(int index, E element) {
rangeCheck(index);
E oldValue = elementData(index);
elementData[index] = element;
return oldValue;
}
源码解析:
- 功能:将集合中下标为index的元素值换为element
- 源码思路:
- (1)首先调用rangeCheck方法判断index下标是否符合条件
- (2)调用elementData方法获取下标为index的元素值,将该值放在oldValue中
- (3)将element值赋给elementData[index]中
- (4)将旧值返回
22. public boolean add(E e)
方法
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
源码解析:
- 功能: 将元素e添加到集合中
- 源码思路:
- (1)首先调用ensureCapacityInternal方法,扩充数组的容量
- (2)将将e的值添加到elementData数组中
23. public void add(int index, E element)
方法
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
源码解析:
- 功能:向数组下标为index的位置,插入元素element
- 源码思路:
- (1)首先调用rangeCheckForAdd方法,判断index是否符合条件
- (2)调用ensureCapacityInternal方法,扩充数组的容量
- (3)将数组中index处及其后面的值向后移动1位
- (4)将element的值赋值给elementData数组的index下标位置
- (5)增加size的大小
24. public E remove(int index)
方法
public E remove(int index) {
rangeCheck(index);
modCount++;
E oldValue = elementData(index);
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
return oldValue;
}
源码解析:
- 功能:将下标为index位置的元素移除
- 源码思路:
- (1)首先调用rangeCheck方法,用来判断index是否符合条件
- (2)更改modCount的值
- (3)调用elementData方法,获取index位置的元素值,放在oldValue变量中
- (4)定义变量numMoved,其值等于size - index - 1,即将第index+1个元素及其后面的元素向前移动
- (5)将最后一个元素赋值为null
- (6)返回删除的元素的信息
25. public boolean remove(Object o)
方法
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
源码解析:
- 功能:从左向右一次遍历,将第一次出现的元素o从集合中删除
- 源码思路:分两种情况进行判断,一种是o为null,另一种是o非null
26. private void fastRemove(int index)
方法
private void fastRemove(int index) {
modCount++;
int numMoved = size - index - 1;
if (numMoved > 0)
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
}
源码解析:
- 功能:将第index元素从集合中删除
- 源码思路:
- (1)首先更改modCount值,因为每从结构上修改一次集合,就要将modCount的值加1
- (2)定义一个变量numMoved,其值等于将要移动的元素的个数
- (3)利用System类的arraycopy方法将第index+1及其后面的元素向前移动一位,即将第index元素覆盖
- (4)将集合最后一个元素赋为null
27. public void clear()
方法
public void clear() {
modCount++;
// clear to let GC do its work
for (int i = 0; i < size; i++)
elementData[i] = null;
size = 0;
}
源码解析:
- 功能:将集合中的元素全部删除
- 源码思路:
- (1)首先修改modCount的值
- (2)利用for循环将集合中的元素全部置于null
- (3)将size的值置为0
28. public boolean addAll(Collection<? extends E> c)
方法
public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}
源码解析:
- 功能:将集合中的元素添加到现有的集合中
- 源码思路:
- (1)定义一个Object类型的数组a,将集合c调用toArray方法,将集合c转换为数组,放在a中
- (2)定义一个变量numNew,用来存储数组a的长度
- (3)调用ensureCapacityInternal方法,扩充modCount
- (4)调用System类的arraycopy方法,将数组a中的元素copy到elementData中,数组a从下标0开始复制,复制到elementData中的下标size位置,复制numNew个元素
- (5)最后更改size的值
29. public boolean addAll(int index, Collection<? extends E> c)
方法
public boolean addAll(int index, Collection<? extends E> c) {
rangeCheckForAdd(index);
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
int numMoved = size - index;
if (numMoved > 0)
System.arraycopy(elementData, index, elementData, index + numNew,
numMoved);
System.arraycopy(a, 0, elementData, index, numNew);
size += numNew;
return numNew != 0;
}
源码解析:
- 功能:将集合中的元素添加到现有的集合中,增加一个添加的下标位置
- 源码思路:与addAll(Collection
30. protected void removeRange(int fromIndex, int toIndex)
方法
protected void removeRange(int fromIndex, int toIndex) {
modCount++;
int numMoved = size - toIndex;
System.arraycopy(elementData, toIndex, elementData, fromIndex,
numMoved);
// clear to let GC do its work
int newSize = size - (toIndex-fromIndex);
for (int i = newSize; i < size; i++) {
elementData[i] = null;
}
size = newSize;
}
源码解析:
- 功能:将集合中的元素从下标fromIndex开始到下标toIndex移除
- 源码思路:
- (1)更改modCount的值,将该值自增1
- (2)定义变量numMoved,该变量的值等于size - toIndex
- (3)调用System类的arraycopy方法,将elementData数组中位置toIndex的值及其后面的值复制到elementData数组的fromIndex位置
- (4)记着将newSize以后的值置为null
- (5)更改size的值
31. private void rangeCheck(int index)
方法
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
源码解析:
- 功能: 判断index是否符合条件
- 源码思路:
- 如果index的值大于等于size的值,即下标的值大于数组的最大值,要抛出异常
32. private void rangeCheckForAdd(int index)
方法
private void rangeCheckForAdd(int index) {
if (index > size || index < 0)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
源码解析:
- 功能:判断将要插入的元素的位置是否符合条件
- 源码思路:
- 插入的元素位置需要小于size大于0才符合条件,否则抛出异常
33. private String outOfBoundsMsg(int index)
方法
private String outOfBoundsMsg(int index) {
return "Index: "+index+", Size: "+size;
}
源码解析:
- 功能:抛出异常时返回的出错信息
- 源码思路:
- 返回元素的位置和集合的大小
34. public boolean removeAll(Collection<?> c)
方法
public boolean removeAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, false);
}
源码解析:
- 功能:移除当前集合中集合c中所有元素
- 源码思路:
- (1)首先调用Objects类的requireNoNull方法,该方法用来判断c是否为null,如果为null则抛出异常,如果不为空,则返回c本身
- (2)移除的操作是调用batchRemove方法实现
35. public boolean retainAll(Collection<?> c)
方法
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
return batchRemove(c, true);
}
源码解析:
- 功能:保留当前集合中所有集合c中的元素
- 源码思路:
- (1)调用Objects类的requireNonNull方法,判断c是否为空
- (2)调用batchRemove方法来实现保存操作
36. private boolean batchRemove(Collection<?> c, boolean complement)
方法
private boolean batchRemove(Collection<?> c, boolean complement) {
final Object[] elementData = this.elementData;
int r = 0, w = 0;
boolean modified = false;
try {
for (; r < size; r++)
if (c.contains(elementData[r]) == complement)
elementData[w++] = elementData[r];
} finally {
// Preserve behavioral compatibility with AbstractCollection,
// even if c.contains() throws.
if (r != size) {
System.arraycopy(elementData, r,
elementData, w,
size - r);
w += size - r;
}
if (w != size) {
// clear to let GC do its work
for (int i = w; i < size; i++)
elementData[i] = null;
modCount += size - w;
size = w;
modified = true;
}
}
return modified;
}
源码解析:
- 功能:批量删除元素,利用complement来判断是删除参数c中的元素,还是保留c中的元素。complement为true,则保留c中的元素,为false则删除c中的元素
- 源码思路:
- (1)定义一个Object类型的数组elementData,将当前集合的elementData值赋值给新定义的elementData
- (2)通过for循环来修改当前集合中的元素信息,如果c中不包含elementData[r]这个元素,则直接将r位置的元素赋值给w位置的元素,w自增
- (3)在finally中,防止抛出异常导致上面r的右移过程没完成 , 将r未右移完成的位置的元素赋值给w右边位置的元素 ,修改w值增加size-r
- (4)如果w不等于size,说明有被覆盖掉的元素,则将w后面的元素都赋值为null ,最后修改size的值
37. public ListIterator<E> listIterator(int index)
方法
public ListIterator<E> listIterator(int index) {
if (index < 0 || index > size)
throw new IndexOutOfBoundsException("Index: "+index);
return new ListItr(index);
}
源码解析:
- 功能:创建ArrayList的迭代器,迭代器有起始位置
- 源码思路:
- (1)首先判断index值是否符合条件,如果不符合条件则抛出异常
- (2)如果符合条件,new一个ListItr,将index值作为参数传递进去,迭代器初始位置为index
38. public ListIterator<E> listIterator()
方法
public ListIterator<E> listIterator() {
return new ListItr(0);
}
源码解析:
- 功能:创建ArrayList的迭代器,迭代器没有起始位置
- 源码思路:
- 直接返回ListItr,迭代器初始位置为0
39. public Iterator<E> iterator()
方法
public Iterator<E> iterator() {
return new Itr();
}
源码解析:
-功能:重写父类的iterator方法
Itr
类
3个成员变量
int cursor; // index of next element to return
int lastRet = -1; // index of last element returned; -1 if no such
int expectedModCount = modCount;
1个构造方法
Itr() {}
1. public boolean hasNext()
方法
public boolean hasNext() {
return cursor != size;
}
源码解析:
- 功能:判断是否还有下一个元素
- 源码思路:
- 通过判断当前的游标是否等于集合的size,就可以判断是否有下一个元素。
2. public E next()
方法
public E next() {
checkForComodification();
int i = cursor;
if (i >= size)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[lastRet = i];
}
源码解析:
- 功能:返回当前元素的下一个元素信息
- 源码思路:
- (1)定义变量i,获取当前迭代器的游标位置。如果i的值大于等于size,说明迭代器已经到达了集合的最后一个位置,抛出异常
- (2)定义Object类型的数组elementData,将当前的集合的elementData数组赋值给新的数组elementData
- (3)如果变量i的值大于等于新定义的数组elementData的长度,抛出异常
- (4)否则返回elementData的第i个元素,并把i的值赋值给lastRet,供下一次操作使用
3. public void remove()
方法
public void remove() {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
源码解析:
- 功能:利用迭代器删除集合中的元素
- 源码思路:
- (1)首先判断lastRet的值是否大于零,如果不大于零,抛出异常
- (2)调用ArrayList类的remove方法,将下标为lastRet的值移除
- (3)更改迭代器游标的当前位置,将其设置为lastRet
- (4)将lastRet设置为-1
- (5)最后要修改迭代器的expectedModCount 值,要将其与modCount保持一致,否则会触发fail-fast机制抛出异常
4. final void checkForComodification()
方法
final void checkForComodification() {
if (modCount != expectedModCount)
throw new ConcurrentModificationException();
}
源码解析:
- 功能:fail-fast机制
- 源码思路:
- 如果迭代器的expectedModCount值与集合的modCount不等,抛出异常
ListItr
类
1. ListItr(int index)
方法
ListItr(int index) {
super();
cursor = index;
}
源码解析:
- 功能:ListItr内部类的构造方法
- 源码思路:将迭代器的游标置于index位置
2. public boolean hasPrevious()
方法
public boolean hasPrevious() {
return cursor != 0;
}
源码解析:
- 功能:判断当前元素前面是否有元素
- 源码思路:如果迭代器的游标值不为0,说明当前元素前面有元素
3. public int nextIndex()
方法
public int nextIndex() {
return cursor;
}
源码解析:
- 功能:返回元素当前位置的迭代器位置
4. public int previousIndex()
方法
public int previousIndex() {
return cursor - 1;
}
5. public E previous()
方法
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
Object[] elementData = ArrayList.this.elementData;
if (i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[lastRet = i];
}
源码解析:
- 功能:返回集合当前元素的前一个元素
- 源码思路:
- (1)定义一个变量i,其值等于迭代器当前游标的前一个游标值
- (2)如果变量i的值小于0,则抛出异常,说明当前位置的前一个位置已经没有元素了
- (3)定义一个Object类型的elementData数组,将当前集合的数组赋给刚定义的数组
- (4)更改迭代器的游标值
6. public void set(E e)
方法
public void set(E e) {
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
ArrayList.this.set(lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
源码解析:
- 功能:利用迭代器更新元素,更改迭代器当前元素的值,其值设置为e
- 源码思路:
- (1)如果lastRet 的值小于0,则抛出异常
- (2)调用ArrayList类的set方法,更改lastRet 位置的元素的值
7. public void add(E e)
方法
public void add(E e) {
checkForComodification();
try {
int i = cursor;
ArrayList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
expectedModCount = modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
源码解析:
- 功能:利用迭代器向集合中添加元素e
- 源码思路:
- (1)定义变量i,其值等于迭代器当前的游标值
- (2)调用ArrayList类的add方法,将e插入集合
- (3)更改迭代器的游标值,因为增加一个元素,所以游标值+1
- (4)设置迭代器的lastRt的值为-1
- (5)更改迭代器的expectedModCount ,使其等于modCount的值