源码镇楼
ArrayList的subList方法,首先调用subListRangeCheck方法做了一个范围检查.
然后创建并返回了一个SubList的内部类对象.
仔细对比SubList和ArrayList的定义.
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
private class SubList extends AbstractList<E> implements RandomAccess
他们同样继承了AbstractList,并实现了RandomAccess标记接口.
而AbstractList是一个抽象类,除了一些抽象方法,还有一些方法干脆没有实现.
比如:
在创建SubList内部类的时候,
new SubList(this, 0, fromIndex, toIndex);
实际上将外部的ArrayList对象,传入了内部类作为一个数据成员,即 AbstractList parent
并且记录了偏移量和Size等信息.
SubList的方法调用,使用了两种方式
1.因为内部类可以访问外部类的方法和属性,所以一些操作直接使用外部类的方法
2.由于内部类 AbstractList parent指向外部类的对象,有一些操作调用parent的方法,通过多态性调用了外部类的方法.
代码风格似乎不太统一..
add和remove都是调用抽象类的方法,通过多态性调用了ArrayList的方法
而get和set方法,又是通过内部类可以直接访问外部类的特性.
有点意思.
- public List<E> subList(int fromIndex, int toIndex) {
- subListRangeCheck(fromIndex, toIndex, size);
- return new SubList(this, 0, fromIndex, toIndex);
- }
- static void subListRangeCheck(int fromIndex, int toIndex, int size) {
- if (fromIndex < 0)
- throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
- if (toIndex > size)
- throw new IndexOutOfBoundsException("toIndex = " + toIndex);
- if (fromIndex > toIndex)
- throw new IllegalArgumentException("fromIndex(" + fromIndex +
- ") > toIndex(" + toIndex + ")");
- }
- private class SubList extends AbstractList<E> implements RandomAccess {
- private final AbstractList<E> parent;
- private final int parentOffset;
- private final int offset;
- int size;
- SubList(AbstractList<E> parent,
- int offset, int fromIndex, int toIndex) {
- this.parent = parent;
- this.parentOffset = fromIndex;
- this.offset = offset + fromIndex;
- this.size = toIndex - fromIndex;
- this.modCount = ArrayList.this.modCount;
- }
- public E set(int index, E e) {
- rangeCheck(index);
- checkForComodification();
- E oldValue = ArrayList.this.elementData(offset + index);
- ArrayList.this.elementData[offset + index] = e;
- return oldValue;
- }
- public E get(int index) {
- rangeCheck(index);
- checkForComodification();
- return ArrayList.this.elementData(offset + index);
- }
- public int size() {
- checkForComodification();
- return this.size;
- }
- public void add(int index, E e) {
- rangeCheckForAdd(index);
- checkForComodification();
- parent.add(parentOffset + index, e);
- this.modCount = parent.modCount;
- this.size++;
- }
- public E remove(int index) {
- rangeCheck(index);
- checkForComodification();
- E result = parent.remove(parentOffset + index);
- this.modCount = parent.modCount;
- this.size--;
- return result;
- }
- protected void removeRange(int fromIndex, int toIndex) {
- checkForComodification();
- parent.removeRange(parentOffset + fromIndex,
- parentOffset + toIndex);
- this.modCount = parent.modCount;
- this.size -= toIndex - fromIndex;
- }
- public boolean addAll(Collection<? extends E> c) {
- return addAll(this.size, c);
- }
- public boolean addAll(int index, Collection<? extends E> c) {
- rangeCheckForAdd(index);
- int cSize = c.size();
- if (cSize==0)
- return false;
- checkForComodification();
- parent.addAll(parentOffset + index, c);
- this.modCount = parent.modCount;
- this.size += cSize;
- return true;
- }
- public Iterator<E> iterator() {
- return listIterator();
- }
- public ListIterator<E> listIterator(final int index) {
- checkForComodification();
- rangeCheckForAdd(index);
- final int offset = this.offset;
- return new ListIterator<E>() {
- int cursor = index;
- int lastRet = -1;
- int expectedModCount = ArrayList.this.modCount;
- public boolean hasNext() {
- return cursor != SubList.this.size;
- }
- @SuppressWarnings("unchecked")
- public E next() {
- checkForComodification();
- int i = cursor;
- if (i >= SubList.this.size)
- throw new NoSuchElementException();
- Object[] elementData = ArrayList.this.elementData;
- if (offset + i >= elementData.length)
- throw new ConcurrentModificationException();
- cursor = i + 1;
- return (E) elementData[offset + (lastRet = i)];
- }
- public boolean hasPrevious() {
- return cursor != 0;
- }
- @SuppressWarnings("unchecked")
- public E previous() {
- checkForComodification();
- int i = cursor - 1;
- if (i < 0)
- throw new NoSuchElementException();
- Object[] elementData = ArrayList.this.elementData;
- if (offset + i >= elementData.length)
- throw new ConcurrentModificationException();
- cursor = i;
- return (E) elementData[offset + (lastRet = i)];
- }
- public int nextIndex() {
- return cursor;
- }
- public int previousIndex() {
- return cursor - 1;
- }
- public void remove() {
- if (lastRet < 0)
- throw new IllegalStateException();
- checkForComodification();
- try {
- SubList.this.remove(lastRet);
- cursor = lastRet;
- lastRet = -1;
- expectedModCount = ArrayList.this.modCount;
- } catch (IndexOutOfBoundsException ex) {
- throw new ConcurrentModificationException();
- }
- }
- public void set(E e) {
- if (lastRet < 0)
- throw new IllegalStateException();
- checkForComodification();
- try {
- ArrayList.this.set(offset + lastRet, e);
- } catch (IndexOutOfBoundsException ex) {
- throw new ConcurrentModificationException();
- }
- }
- public void add(E e) {
- checkForComodification();
- try {
- int i = cursor;
- SubList.this.add(i, e);
- cursor = i + 1;
- lastRet = -1;
- expectedModCount = ArrayList.this.modCount;
- } catch (IndexOutOfBoundsException ex) {
- throw new ConcurrentModificationException();
- }
- }
- final void checkForComodification() {
- if (expectedModCount != ArrayList.this.modCount)
- throw new ConcurrentModificationException();
- }
- };
- }
- public List<E> subList(int fromIndex, int toIndex) {
- subListRangeCheck(fromIndex, toIndex, size);
- return new SubList(this, offset, fromIndex, toIndex);
- }
- private void rangeCheck(int index) {
- if (index < 0 || index >= this.size)
- throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
- }
- private void rangeCheckForAdd(int index) {
- if (index < 0 || index > this.size)
- throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
- }
- private String outOfBoundsMsg(int index) {
- return "Index: "+index+", Size: "+this.size;
- }
- private void checkForComodification() {
- if (ArrayList.this.modCount != this.modCount)
- throw new ConcurrentModificationException();
- }
- }
ArrayList的subList方法,首先调用subListRangeCheck方法做了一个范围检查.
然后创建并返回了一个SubList的内部类对象.
仔细对比SubList和ArrayList的定义.
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
private class SubList extends AbstractList<E> implements RandomAccess
他们同样继承了AbstractList,并实现了RandomAccess标记接口.
而AbstractList是一个抽象类,除了一些抽象方法,还有一些方法干脆没有实现.
比如:
- abstract public E get(int index);
- public E set(int index, E element) {
- throw new UnsupportedOperationException();
- }
- public void add(int index, E element) {
- throw new UnsupportedOperationException();
- }
- public E remove(int index) {
- throw new UnsupportedOperationException();
- }
在创建SubList内部类的时候,
new SubList(this, 0, fromIndex, toIndex);
实际上将外部的ArrayList对象,传入了内部类作为一个数据成员,即 AbstractList parent
并且记录了偏移量和Size等信息.
- private final AbstractList<E> parent;
- private final int parentOffset;
- private final int offset;
- int size;
- SubList(AbstractList<E> parent,
- int offset, int fromIndex, int toIndex) {
- this.parent = parent;
- this.parentOffset = fromIndex;
- this.offset = offset + fromIndex;
- this.size = toIndex - fromIndex;
- this.modCount = ArrayList.this.modCount;
- }
SubList的方法调用,使用了两种方式
1.因为内部类可以访问外部类的方法和属性,所以一些操作直接使用外部类的方法
2.由于内部类 AbstractList parent指向外部类的对象,有一些操作调用parent的方法,通过多态性调用了外部类的方法.
代码风格似乎不太统一..
add和remove都是调用抽象类的方法,通过多态性调用了ArrayList的方法
- public void add(int index, E e) {
- rangeCheckForAdd(index);
- checkForComodification();
- parent.add(parentOffset + index, e);
- this.modCount = parent.modCount;
- this.size++;
- }
- public E remove(int index) {
- rangeCheck(index);
- checkForComodification();
- E result = parent.remove(parentOffset + index);
- this.modCount = parent.modCount;
- this.size--;
- return result;
- }
而get和set方法,又是通过内部类可以直接访问外部类的特性.
- public E set(int index, E e) {
- rangeCheck(index);
- checkForComodification();
- E oldValue = ArrayList.this.elementData(offset + index);
- ArrayList.this.elementData[offset + index] = e;
- return oldValue;
- }
- public E get(int index) {
- rangeCheck(index);
- checkForComodification();
- return ArrayList.this.elementData(offset + index);
- }
有点意思.
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29254281/viewspace-2121834/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/29254281/viewspace-2121834/