Created
July 11, 2013 07:39
-
-
Save lichenbo/5973349 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment