对于AbstractList的子类来说,如果想要处理的是不可修改的list集合,那么只需要实现AbstractList中的get(int index)和int size()方法就足够了。如果要处理的可修改list集合,那么就需要额外实现set(int index, E element)。如果想要处理一个可变长度的list集合,那么还需要实现add(int index, E element)和remove(int index)方法。
除此之外,AbstractList自身实现了iterator和list iterator迭代器的功能。而且,像get(int index)、set(int index, E element)、add(int index, E element)和remove(int index)方法都可以通过随机访问的对集合元素进行操作处理。
在集合尾部加入新的元素e。实际调用的是add(int index, E element)方法。该方法可能会限制e的类型,不满足条件的e可能无法加入到集合中。需要注意的是AbstractList中的add(int index, E element)方法需要被子类重写其实现,否则会抛出UnsupportedOperationException异常。
public void add(int index, E element)
1 2 3
publicvoidadd(int index, E element){ thrownew UnsupportedOperationException(); }
AbstractList中的add(int index, E element)方法直接抛出UnsupportedOperationException异常,需要在子类中重写实现过程。
publicintindexOf(Object o){ ListIterator<E> it = listIterator(); if (o==null) { while (it.hasNext()) if (it.next()==null) return it.previousIndex(); } else { while (it.hasNext()) if (o.equals(it.next())) return it.previousIndex(); } return -1; }
publicintlastIndexOf(Object o){ ListIterator<E> it = listIterator(size()); if (o==null) { while (it.hasPrevious()) if (it.previous()==null) return it.nextIndex(); } else { while (it.hasPrevious()) if (o.equals(it.previous())) return it.nextIndex(); } return -1; }
移除集合中含有的所有元素。实际调用的是removeRange(int fromIndex, int toIndex)方法,因为需要在子类中实现remove(int index)或者removeRange(int fromIndex, int toIndex),所以直接调用AbstractList的clear()方法会抛出UnsupportedOperationException异常。removeRange(int fromIndex, int toIndex)的处理逻辑如下:
1 2 3 4 5 6 7
protectedvoidremoveRange(int fromIndex, int toIndex){ ListIterator<E> it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i<n; i++) { it.next(); it.remove(); } }
移除list集合中从fromIndex 到 toIndex的所有元素。删除的元素中包含fromIndex位置的元素,但是不包括toIndex位置的元素。方法执行完成后会将toIndex之后的元素前移填补空缺位置。由于第5行代码调用的remove()方法底层实际调用的是remove(int index)方法,而该方法在AbstractList中直接抛出UnsupportedOperationException异常,所以子类需要重写removeRange(int fromIndex, int toIndex)或者remove(int index)。
public boolean addAll(int index, Collection<? extends E> c)
1 2 3 4 5 6 7 8 9
publicbooleanaddAll(int index, Collection<? extends E> c){ rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; }
将c中的所有元素加入到list集合中自index起的位置上,自index位置起的元素会后移以便为c中的元素提供空间。第2行代码会检查当前list集合的剩余空间情况。之后遍历c中的每个元素,调用add(int index, E element)方法将其保存到list集合中。AbstractList中的add(int index, E element)方法由于需要子类实现,所以会直接抛出UnsupportedOperationException异常。
1 2 3 4 5 6 7 8
privatevoidrangeCheckForAdd(int index){ if (index < 0 || index > size()) thrownew IndexOutOfBoundsException(outOfBoundsMsg(index)); }
privateclassItrimplementsIterator<E> { /** * Index of element to be returned by subsequent call to next. */ int cursor = 0;
/** * Index of element returned by most recent call to next or * previous. Reset to -1 if this element is deleted by a call * to remove. */ int lastRet = -1;
/** * The modCount value that the iterator believes that the backing * List should have. If this expectation is violated, the iterator * has detected concurrent modification. */ int expectedModCount = modCount;
public E next(){ checkForComodification(); try { int i = cursor; E next = get(i); lastRet = i; cursor = i + 1; return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); thrownew NoSuchElementException(); } }
publicvoidremove(){ if (lastRet < 0) thrownew IllegalStateException(); checkForComodification();
第31 ~ 42行代码将lastRet位置的元素替换为参数e。如果lastRet小于0,那么认为在调用set(E e)方法之前尚未调用过next()或者previous()方法,那么此时无法通过set(E e)方法实现元素替换。接着会检查当前list集合的最近一次修改是否是由当前迭代器执行的,如果不是,则会抛出异常。如果检查通过,那么调用AbstractList中的set(int index, E element)方法完成元素的替换。最后更新expectedModCount的值标记当前迭代器对list集合做出了修改。
第44 ~ 56行代码将新的元素e加入到cursor标识的位置上。在完成当前list集合的最近一次修改是否是由当前迭代器执行的检查后,通过AbstractList中的add(int index, E element)方法完成元素的加入。操作完成后将lastRet重置为-1,同时将cursor移动到下一个位置上。最后更新expectedModCount的值完成所有操作。
图1描述了ListIterator中关于cursor游标是如何工作的:
图 - 1
public List<E> subList(int fromIndex, int toIndex)
1 2 3 4 5
public List<E> subList(int fromIndex, int toIndex){ return (thisinstanceof RandomAccess ? new RandomAccessSubList<>(this, fromIndex, toIndex) : new SubList<>(this, fromIndex, toIndex)); }
// 构造函数,完成初始化操作 SubList(AbstractList<E> list, int fromIndex, int toIndex) { if (fromIndex < 0) thrownew IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > list.size()) thrownew IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) thrownew IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); l = list; offset = fromIndex; size = toIndex - fromIndex; this.modCount = l.modCount; }
// 用element替换到子list集合中index位置处的元素,实际调用AbstractList中的set(int index, E element)方法。 public E set(int index, E element){ rangeCheck(index); checkForComodification(); return l.set(index+offset, element); }
// 获取index位置的元素,实际调用AbstractList中的get(int index)方法。 public E get(int index){ rangeCheck(index); checkForComodification(); return l.get(index+offset); }
// 将element加入到子list集合中index位置处,实际调用AbstractList中的add(int index, E element)方法。 publicvoidadd(int index, E element){ rangeCheckForAdd(index); checkForComodification(); l.add(index+offset, element); this.modCount = l.modCount; size++; }
// 移除index位置的元素,实际调用AbstractList中的remove(int index)方法。 public E remove(int index){ rangeCheck(index); checkForComodification(); E result = l.remove(index+offset); this.modCount = l.modCount; size--; return result; }
// 移除自fromIndex起到toIndex为止的元素,实际调用AbstractList中的gremoveRange(int fromIndex, int toIndex)方法。 protectedvoidremoveRange(int fromIndex, int toIndex){ checkForComodification(); l.removeRange(fromIndex+offset, toIndex+offset); this.modCount = l.modCount; size -= (toIndex-fromIndex); }