源码镇楼
-
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博客 ” ,链接:https://blog.itpub.net/29254281/viewspace-2121834/
,如需转载,请注明出处,否则将追究法律责任。