< prev index next >
src/java.base/share/classes/java/util/ArrayList.java
Print this page
rev 13550 : [mq]: 8079136-Nested-SubLists
*** 1,7 ****
/*
! * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
--- 1,7 ----
/*
! * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
*** 702,712 ****
* Constructs an IndexOutOfBoundsException detail message.
* Of the many possible refactorings of the error handling code,
* this "outlining" performs best with both server and client VMs.
*/
private String outOfBoundsMsg(int index) {
! return "Index: "+index+", Size: "+size;
}
/**
* A version used in checking (fromIndex > toIndex) condition
*/
--- 702,712 ----
* Constructs an IndexOutOfBoundsException detail message.
* Of the many possible refactorings of the error handling code,
* this "outlining" performs best with both server and client VMs.
*/
private String outOfBoundsMsg(int index) {
! return "Index: " + index + ", Size: " + size;
}
/**
* A version used in checking (fromIndex > toIndex) condition
*/
*** 1040,1151 ****
* @throws IndexOutOfBoundsException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
*/
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;
}
--- 1040,1147 ----
* @throws IndexOutOfBoundsException {@inheritDoc}
* @throws IllegalArgumentException {@inheritDoc}
*/
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
! return new SubList<>(this, fromIndex, toIndex);
}
! private static class SubList<E> extends AbstractList<E> implements RandomAccess {
! private final ArrayList<E> root;
! private final SubList<E> parent;
private final int offset;
! private int size;
!
! /**
! * Constructs a sublist of an arbitrary ArrayList.
! */
! public SubList(ArrayList<E> root, int fromIndex, int toIndex) {
! this.root = root;
! this.parent = null;
! this.offset = fromIndex;
! this.size = toIndex - fromIndex;
! this.modCount = root.modCount;
! }
! /**
! * Constructs a sublist of another SubList.
! */
! private SubList(SubList<E> parent, int fromIndex, int toIndex) {
! this.root = parent.root;
this.parent = parent;
! this.offset = parent.offset + fromIndex;
this.size = toIndex - fromIndex;
! this.modCount = root.modCount;
}
! public E set(int index, E element) {
rangeCheck(index);
checkForComodification();
! E oldValue = root.elementData(offset + index);
! root.elementData[offset + index] = element;
return oldValue;
}
public E get(int index) {
rangeCheck(index);
checkForComodification();
! return root.elementData(offset + index);
}
public int size() {
checkForComodification();
! return size;
}
! public void add(int index, E element) {
rangeCheckForAdd(index);
checkForComodification();
! root.add(offset + index, element);
! updateSizeAndModCount(1);
}
public E remove(int index) {
rangeCheck(index);
checkForComodification();
! E result = root.remove(offset + index);
! updateSizeAndModCount(-1);
return result;
}
protected void removeRange(int fromIndex, int toIndex) {
checkForComodification();
! root.removeRange(offset + fromIndex, offset + toIndex);
! updateSizeAndModCount(fromIndex - toIndex);
}
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();
! root.addAll(offset + index, c);
! updateSizeAndModCount(cSize);
return true;
}
public Iterator<E> iterator() {
return listIterator();
}
! public ListIterator<E> listIterator(int index) {
checkForComodification();
rangeCheckForAdd(index);
return new ListIterator<E>() {
int cursor = index;
int lastRet = -1;
! int expectedModCount = root.modCount;
public boolean hasNext() {
return cursor != SubList.this.size;
}
*** 1153,1163 ****
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)];
}
--- 1149,1159 ----
public E next() {
checkForComodification();
int i = cursor;
if (i >= SubList.this.size)
throw new NoSuchElementException();
! Object[] elementData = root.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i + 1;
return (E) elementData[offset + (lastRet = i)];
}
*** 1170,1180 ****
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)];
}
--- 1166,1176 ----
public E previous() {
checkForComodification();
int i = cursor - 1;
if (i < 0)
throw new NoSuchElementException();
! Object[] elementData = root.elementData;
if (offset + i >= elementData.length)
throw new ConcurrentModificationException();
cursor = i;
return (E) elementData[offset + (lastRet = i)];
}
*** 1185,1195 ****
final int size = SubList.this.size;
int i = cursor;
if (i >= size) {
return;
}
! final Object[] elementData = ArrayList.this.elementData;
if (offset + i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[offset + (i++)]);
--- 1181,1191 ----
final int size = SubList.this.size;
int i = cursor;
if (i >= size) {
return;
}
! final Object[] elementData = root.elementData;
if (offset + i >= elementData.length) {
throw new ConcurrentModificationException();
}
while (i != size && modCount == expectedModCount) {
consumer.accept((E) elementData[offset + (i++)]);
*** 1214,1224 ****
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
! expectedModCount = ArrayList.this.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
--- 1210,1220 ----
try {
SubList.this.remove(lastRet);
cursor = lastRet;
lastRet = -1;
! expectedModCount = root.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
*** 1226,1236 ****
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
! ArrayList.this.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
--- 1222,1232 ----
if (lastRet < 0)
throw new IllegalStateException();
checkForComodification();
try {
! root.set(offset + lastRet, e);
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
*** 1240,1290 ****
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();
}
public Spliterator<E> spliterator() {
checkForComodification();
! return new ArrayListSpliterator<>(ArrayList.this, offset,
! offset + this.size, this.modCount);
}
}
@Override
public void forEach(Consumer<? super E> action) {
--- 1236,1295 ----
try {
int i = cursor;
SubList.this.add(i, e);
cursor = i + 1;
lastRet = -1;
! expectedModCount = root.modCount;
} catch (IndexOutOfBoundsException ex) {
throw new ConcurrentModificationException();
}
}
final void checkForComodification() {
! if (root.modCount != expectedModCount)
throw new ConcurrentModificationException();
}
};
}
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
! 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 (root.modCount != 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);
+ }
+
public Spliterator<E> spliterator() {
checkForComodification();
! return new ArrayListSpliterator<>(root, offset,
! offset + size, modCount);
}
}
@Override
public void forEach(Consumer<? super E> action) {
< prev index next >