< prev index next >
src/java.base/share/classes/java/util/AbstractList.java
Print this page
rev 11832 : [mq]: 8079136-NestedSubList
@@ -491,13 +491,24 @@
* {@code (fromIndex < 0 || toIndex > size)}
* @throws IllegalArgumentException if the endpoint indices are out of order
* {@code (fromIndex > toIndex)}
*/
public List<E> subList(int fromIndex, int toIndex) {
+ subListRangeCheck(fromIndex, toIndex, size());
return (this instanceof RandomAccess ?
- new RandomAccessSubList<>(this, fromIndex, toIndex) :
- new SubList<>(this, fromIndex, toIndex));
+ new RandomAccessSubList<>(this, null, 0, fromIndex, toIndex) :
+ new SubList<>(this, null, 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 + ")");
}
// Comparison and hashing
/**
@@ -619,101 +630,93 @@
if (index < 0 || index > size())
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
- return "Index: "+index+", Size: "+size();
+ return "Index: " + index + ", Size: " + size();
}
}
class SubList<E> extends AbstractList<E> {
- private final AbstractList<E> l;
- private final int offset;
- private int 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;
+ final AbstractList<E> root;
+ final SubList<E> parent;
+ final int offset;
+ int size;
+
+ SubList(AbstractList<E> root, SubList<E> parent,
+ int offset, int fromIndex, int toIndex) {
+ this.root = root;
+ this.parent = parent;
+ this.offset = offset + fromIndex;
+ this.size = toIndex - fromIndex;
+ this.modCount = root.modCount;
}
public E set(int index, E element) {
rangeCheck(index);
checkForComodification();
- return l.set(index+offset, element);
+ return root.set(offset + index, element);
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
- return l.get(index+offset);
+ return root.get(offset + index);
}
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++;
+ root.add(offset + index, element);
+ updateSizeAndModCount(1);
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
- E result = l.remove(index+offset);
- this.modCount = l.modCount;
- size--;
+ E result = root.remove(offset + index);
+ updateSizeAndModCount(-1);
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
- l.removeRange(fromIndex+offset, toIndex+offset);
- this.modCount = l.modCount;
- size -= (toIndex-fromIndex);
+ root.removeRange(offset + fromIndex, offset + toIndex);
+ updateSizeAndModCount(fromIndex - toIndex);
}
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)
+ if (cSize == 0)
return false;
-
checkForComodification();
- l.addAll(offset+index, c);
- this.modCount = l.modCount;
- size += cSize;
+ root.addAll(offset + index, c);
+ updateSizeAndModCount(cSize);
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
- public ListIterator<E> listIterator(final int index) {
+ public ListIterator<E> listIterator(int index) {
checkForComodification();
rangeCheckForAdd(index);
return new ListIterator<E>() {
- private final ListIterator<E> i = l.listIterator(index+offset);
+ private final ListIterator<E> i =
+ root.listIterator(offset + index);
public boolean hasNext() {
return nextIndex() < size;
}
@@ -743,28 +746,27 @@
return i.previousIndex() - offset;
}
public void remove() {
i.remove();
- SubList.this.modCount = l.modCount;
- size--;
+ updateSizeAndModCount(-1);
}
public void set(E e) {
i.set(e);
}
public void add(E e) {
i.add(e);
- SubList.this.modCount = l.modCount;
- size++;
+ updateSizeAndModCount(1);
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
- return new SubList<>(this, fromIndex, toIndex);
+ subListRangeCheck(fromIndex, toIndex, size);
+ return new SubList<>(root, this, offset, fromIndex, toIndex);
}
private void rangeCheck(int index) {
if (index < 0 || index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
@@ -774,23 +776,37 @@
if (index < 0 || index > size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}
private String outOfBoundsMsg(int index) {
- return "Index: "+index+", Size: "+size;
+ return "Index: " + index + ", Size: " + size;
}
private void checkForComodification() {
- if (this.modCount != l.modCount)
+ if (root.modCount != this.modCount)
throw new ConcurrentModificationException();
}
+
+ private void updateSizeAndModCount(int sizeChange) {
+ SubList<E> slist = this;
+ do {
+ slist.size += sizeChange;
+ slist.modCount = root.modCount;
+ slist = slist.parent;
+ } while (slist != null);
+ }
}
-class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {
- RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {
- super(list, fromIndex, toIndex);
+class RandomAccessSubList<E> extends SubList<E>
+ implements RandomAccess {
+
+ RandomAccessSubList(AbstractList<E> root, SubList<E> parent,
+ int offset, int fromIndex, int toIndex) {
+ super(root, parent, offset, fromIndex, toIndex);
}
public List<E> subList(int fromIndex, int toIndex) {
- return new RandomAccessSubList<>(this, fromIndex, toIndex);
+ subListRangeCheck(fromIndex, toIndex, size);
+ return new RandomAccessSubList<>(root, this, offset,
+ fromIndex, toIndex);
}
}
< prev index next >