// differences to AbstractList.subList / ArrayList.subList: // -probably doesn't handle modCount the same way // // made from AbstractList.subList sclass SubList extends AbstractList implements ISubList { L root; SubList parent; int offset; int size; /** * Constructs a sublist of an arbitrary AbstractList, which is * not a SubList itself. */ public SubList(L root, int fromIndex, int toIndex) { if (root cast SubList) { this.parent = root; this.root = root.root; this.offset = root.offset + fromIndex; } else { this.parent = null; this.root = root; this.offset = fromIndex; } this.size = toIndex - fromIndex; } public E set(int index, E element) { Objects.checkIndex(index, size); checkForComodification(); return root.set(offset + index, element); } public E get(int index) { Objects.checkIndex(index, size); checkForComodification(); return root.get(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) { Objects.checkIndex(index, size); checkForComodification(); E result = root.remove(offset + index); updateSizeAndModCount(-1); return result; } protected void removeRange(int fromIndex, int toIndex) { checkForComodification(); root.subList(offset + fromIndex, offset + toIndex).clear(); updateSizeAndModCount(fromIndex - toIndex); } public boolean addAll(Collection c) { return addAll(size, c); } public boolean addAll(int index, Collection c) { rangeCheckForAdd(index); int cSize = c.size(); if (cSize==0) return false; checkForComodification(); root.addAll(offset + index, c); updateSizeAndModCount(cSize); return true; } public Iterator iterator() { return listIterator(); } public ListIterator listIterator(int index) { checkForComodification(); rangeCheckForAdd(index); return new ListIterator() { private final ListIterator i = root.listIterator(offset + index); public boolean hasNext() { return nextIndex() < size; } public E next() { if (hasNext()) return i.next(); else throw new NoSuchElementException(); } public boolean hasPrevious() { return previousIndex() >= 0; } public E previous() { if (hasPrevious()) return i.previous(); else throw new NoSuchElementException(); } public int nextIndex() { return i.nextIndex() - offset; } public int previousIndex() { return i.previousIndex() - offset; } public void remove() { i.remove(); updateSizeAndModCount(-1); } public void set(E e) { i.set(e); } public void add(E e) { i.add(e); updateSizeAndModCount(1); } }; } public List subList(int fromIndex, int toIndex) { _subListRangeCheck(fromIndex, toIndex, size); return new SubList<>(this, fromIndex, toIndex); } 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() {} private void updateSizeAndModCount(int sizeChange) { SubList slist = this; do { slist.size += sizeChange; slist = slist.parent; } while (slist != null); } public L rootList() { ret root; } public L parentList() { ret parent; } public int subListOffset() { ret offset; } }