一 AbstractList类的继承关系
可以看到这里有一个类是它本身的类,第二个类和第三个都是他的子类:SubList 和RandomAccessSubList,慢慢看。
二 AbstractList类本身的继承结构
可以看到它内部实现了除了实现了List接口的方法和继承实现了抽象Collection的方法外,内部还实现了两个迭代器:Itr 和 ListItr。
此外他还有一个关键的变量
modCount :它的释义是:集合被改变的次数。如果该值发生意外的改变则会抛出ConcurrentModificationException并发修改异常当然是在next remove previous set add 方法中。当然这个字段对于子类来说是可选的,可以忽略。
三 先看下其中最下面新增的几个方法:
删除指定区间的元素,通过迭代器遍历 protected void removeRange(int fromIndex, int toIndex) { ListIterator<E> it = listIterator(fromIndex); for (int i=0, n=toIndex-fromIndex; i<n; i++) { it.next(); it.remove(); } }
索引判断 private void rangeCheckForAdd(int index) { if (index < 0 || index > size()) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); }
显示当前索引和集合大小 private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size(); }
四 实现自list接口的方法和AbstractCollection的方法
set ,add,remove 操作都是默认抛出不支持操作异常的方法。
查找元素索引值,可以为空,所以判断。 public int indexOf(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; } 查找元素最后一次出现的索引值,可以为空,所以判断。 public int lastIndexOf(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; }
清空方法调用删除指定区间的方法。 public void clear() { removeRange(0, size()); }
通过指定索引值插入集合中的所有元素,遍历插入。 public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); boolean modified = false; for (E e : c) { add(index++, e); modified = true; } return modified; }
五 再来看看内部类里面的的Itr迭代器类
可以看到有三个变量,一个一个看。
cursor :元素的索引,将由后续调用next返回。
lastRet:最近一个调用next 和 previous 保存下来的索引值,若元素删除,则重置为0
expectedModCount:
返回当前游标是不是达到集合元素的最大值 public boolean hasNext() { return cursor != size(); }
返回迭代器指向的下一个元素 public E next() { checkForComodification(); try { int i = cursor; //当前游标索引值 E next = get(i);//得到元素 lastRet = i;//保存最近一次next的索引值 cursor = i + 1;//游标++ return next; } catch (IndexOutOfBoundsException e) { checkForComodification(); throw new NoSuchElementException(); } }
迭代器提供了删除方法,删除自上一个next 或 pervious 保存的索引值, public void remove() { if (lastRet < 0) throw new IllegalStateException(); checkForComodification(); try { AbstractList.this.remove(lastRet); if (lastRet < cursor) cursor--;将游标退回 lastRet = -1;重置为-1 expectedModCount = modCount; } catch (IndexOutOfBoundsException e) { throw new ConcurrentModificationException(); } }
判断当前是不是有多个线程在修改,是的话,抛出并行操作异常 final void checkForComodification() { if (modCount != expectedModCount) throw new ConcurrentModificationException(); }
六 ListItr
该类在继承了Itr的基础上还实现了ListIterator的方法
主要是多了前后遍历访问的功能,线性表。
七 看完了内部类,再看下另外两个子类 先看SubList
该类可以截取集合中的元素返回一个他的子类,实际根本就没有返回新集合,还是原来的集合,根据构造函数fromIndex,toIndex设置了偏移量offset=fromIndex,和size=toIndex-fromIndex。每次还是操作的原集合,只不过加了一个偏移量offset。
有三个变量:
class SubList<E> extends AbstractList<E> { private final AbstractList<E> l; 传入的集合类 private final int offset; 偏移量 private int size; 截取的元素size SubList(AbstractList<E> list, int fromIndex, int toIndex) { if (fromIndex < 0) throw new IndexOutOfBoundsException("fromIndex = " + fromIndex); if (toIndex > list.size()) throw new IndexOutOfBoundsException("toIndex = " + toIndex); if (fromIndex > toIndex) throw new IllegalArgumentException("fromIndex(" + fromIndex + ") > toIndex(" + toIndex + ")"); l = list; offset = fromIndex; size = toIndex - fromIndex; this.modCount = l.modCount; } public E set(int index, E element) { rangeCheck(index); checkForComodification(); return l.set(index+offset, element); } public E get(int index) { rangeCheck(index); checkForComodification(); return l.get(index+offset); } public int size() { checkForComodification(); return size; } public void add(int index, E element) { rangeCheckForAdd(index); checkForComodification(); l.add(index+offset, element); this.modCount = l.modCount; size++; } public E remove(int index) { rangeCheck(index); checkForComodification(); E result = l.remove(index+offset); this.modCount = l.modCount; size--; return result; } protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); l.removeRange(fromIndex+offset, toIndex+offset); this.modCount = l.modCount; size -= (toIndex-fromIndex); } public boolean addAll(Collection<? extends E> c) { return addAll(size, c); } public boolean addAll(int index, Collection<? extends E> c) { rangeCheckForAdd(index); int cSize = c.size(); if (cSize==0) return false; checkForComodification(); l.addAll(offset+index, c); this.modCount = l.modCount; size += cSize; return true; } public Iterator<E> iterator() { return listIterator(); } public ListIterator<E> listIterator(final int index) { checkForComodification(); rangeCheckForAdd(index); return new ListIterator<E>() { private final ListIterator<E> i = l.listIterator(index+offset); public boolean hasNext() { return nextIndex() < size; } public E next() { if (hasNext()) return i.next(); else throw new NoSuchElementException(); } public boolean hasPrevious() { return previousIndex() >= 0; } public E previous() { if (hasPrevious()) return i.previous(); else throw new NoSuchElementException(); } public int nextIndex() { return i.nextIndex() - offset; } public int previousIndex() { return i.previousIndex() - offset; } public void remove() { i.remove(); SubList.this.modCount = l.modCount; size--; } public void set(E e) { i.set(e); } public void add(E e) { i.add(e); SubList.this.modCount = l.modCount; size++; } }; } public List<E> subList(int fromIndex, int toIndex) { return new SubList<>(this, fromIndex, toIndex); //这里返回的对象还是传入的集合类本身 } //索引判断是否越界 private void rangeCheck(int index) { if (index < 0 || index >= size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private void rangeCheckForAdd(int index) { if (index < 0 || index > size) throw new IndexOutOfBoundsException(outOfBoundsMsg(index)); } private String outOfBoundsMsg(int index) { return "Index: "+index+", Size: "+size; } private void checkForComodification() { if (this.modCount != l.modCount) throw new ConcurrentModificationException(); } }
八 最后看下RandomAccessSubList
这玩意就是继承自面SubList并且实现了RandomAccess随机访问接口的实现类。
class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
super(list, fromIndex, toIndex);
}
public List<E> subList(int fromIndex, int toIndex) {
return new RandomAccessSubList<>(this, fromIndex, toIndex);
}
}
总结:SubList 那里应该注意下,返回的截取后的list还是传入时的list,如果add等等操作后,原来的list也会变化。
还要了解下RandomAccess接口啊。看了一篇文章,大概了解了这个接口的作用。标记接口,通常做判断用,然后根据判断是狗实现RandomAccess接口,在调用高效的算法进行处理访问。https://blog.youkuaiyun.com/ted_cs/article/details/82852093连接在这!!