< 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 >