Path: blob/master/src/java.base/share/classes/java/util/AbstractList.java
41152 views
/*1* Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package java.util;2627import java.util.function.Consumer;2829/**30* This class provides a skeletal implementation of the {@link List}31* interface to minimize the effort required to implement this interface32* backed by a "random access" data store (such as an array). For sequential33* access data (such as a linked list), {@link AbstractSequentialList} should34* be used in preference to this class.35*36* <p>To implement an unmodifiable list, the programmer needs only to extend37* this class and provide implementations for the {@link #get(int)} and38* {@link List#size() size()} methods.39*40* <p>To implement a modifiable list, the programmer must additionally41* override the {@link #set(int, Object) set(int, E)} method (which otherwise42* throws an {@code UnsupportedOperationException}). If the list is43* variable-size the programmer must additionally override the44* {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.45*46* <p>The programmer should generally provide a void (no argument) and collection47* constructor, as per the recommendation in the {@link Collection} interface48* specification.49*50* <p>Unlike the other abstract collection implementations, the programmer does51* <i>not</i> have to provide an iterator implementation; the iterator and52* list iterator are implemented by this class, on top of the "random access"53* methods:54* {@link #get(int)},55* {@link #set(int, Object) set(int, E)},56* {@link #add(int, Object) add(int, E)} and57* {@link #remove(int)}.58*59* <p>The documentation for each non-abstract method in this class describes its60* implementation in detail. Each of these methods may be overridden if the61* collection being implemented admits a more efficient implementation.62*63* <p>This class is a member of the64* <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">65* Java Collections Framework</a>.66*67* @author Josh Bloch68* @author Neal Gafter69* @since 1.270*/7172public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {73/**74* Sole constructor. (For invocation by subclass constructors, typically75* implicit.)76*/77protected AbstractList() {78}7980/**81* Appends the specified element to the end of this list (optional82* operation).83*84* <p>Lists that support this operation may place limitations on what85* elements may be added to this list. In particular, some86* lists will refuse to add null elements, and others will impose87* restrictions on the type of elements that may be added. List88* classes should clearly specify in their documentation any restrictions89* on what elements may be added.90*91* @implSpec92* This implementation calls {@code add(size(), e)}.93*94* <p>Note that this implementation throws an95* {@code UnsupportedOperationException} unless96* {@link #add(int, Object) add(int, E)} is overridden.97*98* @param e element to be appended to this list99* @return {@code true} (as specified by {@link Collection#add})100* @throws UnsupportedOperationException if the {@code add} operation101* is not supported by this list102* @throws ClassCastException if the class of the specified element103* prevents it from being added to this list104* @throws NullPointerException if the specified element is null and this105* list does not permit null elements106* @throws IllegalArgumentException if some property of this element107* prevents it from being added to this list108*/109public boolean add(E e) {110add(size(), e);111return true;112}113114/**115* {@inheritDoc}116*117* @throws IndexOutOfBoundsException {@inheritDoc}118*/119public abstract E get(int index);120121/**122* {@inheritDoc}123*124* @implSpec125* This implementation always throws an126* {@code UnsupportedOperationException}.127*128* @throws UnsupportedOperationException {@inheritDoc}129* @throws ClassCastException {@inheritDoc}130* @throws NullPointerException {@inheritDoc}131* @throws IllegalArgumentException {@inheritDoc}132* @throws IndexOutOfBoundsException {@inheritDoc}133*/134public E set(int index, E element) {135throw new UnsupportedOperationException();136}137138/**139* {@inheritDoc}140*141* @implSpec142* This implementation always throws an143* {@code UnsupportedOperationException}.144*145* @throws UnsupportedOperationException {@inheritDoc}146* @throws ClassCastException {@inheritDoc}147* @throws NullPointerException {@inheritDoc}148* @throws IllegalArgumentException {@inheritDoc}149* @throws IndexOutOfBoundsException {@inheritDoc}150*/151public void add(int index, E element) {152throw new UnsupportedOperationException();153}154155/**156* {@inheritDoc}157*158* @implSpec159* This implementation always throws an160* {@code UnsupportedOperationException}.161*162* @throws UnsupportedOperationException {@inheritDoc}163* @throws IndexOutOfBoundsException {@inheritDoc}164*/165public E remove(int index) {166throw new UnsupportedOperationException();167}168169170// Search Operations171172/**173* {@inheritDoc}174*175* @implSpec176* This implementation first gets a list iterator (with177* {@code listIterator()}). Then, it iterates over the list until the178* specified element is found or the end of the list is reached.179*180* @throws ClassCastException {@inheritDoc}181* @throws NullPointerException {@inheritDoc}182*/183public int indexOf(Object o) {184ListIterator<E> it = listIterator();185if (o==null) {186while (it.hasNext())187if (it.next()==null)188return it.previousIndex();189} else {190while (it.hasNext())191if (o.equals(it.next()))192return it.previousIndex();193}194return -1;195}196197/**198* {@inheritDoc}199*200* @implSpec201* This implementation first gets a list iterator that points to the end202* of the list (with {@code listIterator(size())}). Then, it iterates203* backwards over the list until the specified element is found, or the204* beginning of the list is reached.205*206* @throws ClassCastException {@inheritDoc}207* @throws NullPointerException {@inheritDoc}208*/209public int lastIndexOf(Object o) {210ListIterator<E> it = listIterator(size());211if (o==null) {212while (it.hasPrevious())213if (it.previous()==null)214return it.nextIndex();215} else {216while (it.hasPrevious())217if (o.equals(it.previous()))218return it.nextIndex();219}220return -1;221}222223224// Bulk Operations225226/**227* Removes all of the elements from this list (optional operation).228* The list will be empty after this call returns.229*230* @implSpec231* This implementation calls {@code removeRange(0, size())}.232*233* <p>Note that this implementation throws an234* {@code UnsupportedOperationException} unless {@code remove(int235* index)} or {@code removeRange(int fromIndex, int toIndex)} is236* overridden.237*238* @throws UnsupportedOperationException if the {@code clear} operation239* is not supported by this list240*/241public void clear() {242removeRange(0, size());243}244245/**246* {@inheritDoc}247*248* @implSpec249* This implementation gets an iterator over the specified collection250* and iterates over it, inserting the elements obtained from the251* iterator into this list at the appropriate position, one at a time,252* using {@code add(int, E)}.253* Many implementations will override this method for efficiency.254*255* <p>Note that this implementation throws an256* {@code UnsupportedOperationException} unless257* {@link #add(int, Object) add(int, E)} is overridden.258*259* @throws UnsupportedOperationException {@inheritDoc}260* @throws ClassCastException {@inheritDoc}261* @throws NullPointerException {@inheritDoc}262* @throws IllegalArgumentException {@inheritDoc}263* @throws IndexOutOfBoundsException {@inheritDoc}264*/265public boolean addAll(int index, Collection<? extends E> c) {266rangeCheckForAdd(index);267boolean modified = false;268for (E e : c) {269add(index++, e);270modified = true;271}272return modified;273}274275276// Iterators277278/**279* Returns an iterator over the elements in this list in proper sequence.280*281* @implSpec282* This implementation returns a straightforward implementation of the283* iterator interface, relying on the backing list's {@code size()},284* {@code get(int)}, and {@code remove(int)} methods.285*286* <p>Note that the iterator returned by this method will throw an287* {@link UnsupportedOperationException} in response to its288* {@code remove} method unless the list's {@code remove(int)} method is289* overridden.290*291* <p>This implementation can be made to throw runtime exceptions in the292* face of concurrent modification, as described in the specification293* for the (protected) {@link #modCount} field.294*295* @return an iterator over the elements in this list in proper sequence296*/297public Iterator<E> iterator() {298return new Itr();299}300301/**302* {@inheritDoc}303*304* @implSpec305* This implementation returns {@code listIterator(0)}.306*307* @see #listIterator(int)308*/309public ListIterator<E> listIterator() {310return listIterator(0);311}312313/**314* {@inheritDoc}315*316* @implSpec317* This implementation returns a straightforward implementation of the318* {@code ListIterator} interface that extends the implementation of the319* {@code Iterator} interface returned by the {@code iterator()} method.320* The {@code ListIterator} implementation relies on the backing list's321* {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}322* and {@code remove(int)} methods.323*324* <p>Note that the list iterator returned by this implementation will325* throw an {@link UnsupportedOperationException} in response to its326* {@code remove}, {@code set} and {@code add} methods unless the327* list's {@code remove(int)}, {@code set(int, E)}, and328* {@code add(int, E)} methods are overridden.329*330* <p>This implementation can be made to throw runtime exceptions in the331* face of concurrent modification, as described in the specification for332* the (protected) {@link #modCount} field.333*334* @throws IndexOutOfBoundsException {@inheritDoc}335*/336public ListIterator<E> listIterator(final int index) {337rangeCheckForAdd(index);338339return new ListItr(index);340}341342private class Itr implements Iterator<E> {343/**344* Index of element to be returned by subsequent call to next.345*/346int cursor = 0;347348/**349* Index of element returned by most recent call to next or350* previous. Reset to -1 if this element is deleted by a call351* to remove.352*/353int lastRet = -1;354355/**356* The modCount value that the iterator believes that the backing357* List should have. If this expectation is violated, the iterator358* has detected concurrent modification.359*/360int expectedModCount = modCount;361362public boolean hasNext() {363return cursor != size();364}365366public E next() {367checkForComodification();368try {369int i = cursor;370E next = get(i);371lastRet = i;372cursor = i + 1;373return next;374} catch (IndexOutOfBoundsException e) {375checkForComodification();376throw new NoSuchElementException(e);377}378}379380public void remove() {381if (lastRet < 0)382throw new IllegalStateException();383checkForComodification();384385try {386AbstractList.this.remove(lastRet);387if (lastRet < cursor)388cursor--;389lastRet = -1;390expectedModCount = modCount;391} catch (IndexOutOfBoundsException e) {392throw new ConcurrentModificationException();393}394}395396final void checkForComodification() {397if (modCount != expectedModCount)398throw new ConcurrentModificationException();399}400}401402private class ListItr extends Itr implements ListIterator<E> {403ListItr(int index) {404cursor = index;405}406407public boolean hasPrevious() {408return cursor != 0;409}410411public E previous() {412checkForComodification();413try {414int i = cursor - 1;415E previous = get(i);416lastRet = cursor = i;417return previous;418} catch (IndexOutOfBoundsException e) {419checkForComodification();420throw new NoSuchElementException(e);421}422}423424public int nextIndex() {425return cursor;426}427428public int previousIndex() {429return cursor-1;430}431432public void set(E e) {433if (lastRet < 0)434throw new IllegalStateException();435checkForComodification();436437try {438AbstractList.this.set(lastRet, e);439expectedModCount = modCount;440} catch (IndexOutOfBoundsException ex) {441throw new ConcurrentModificationException();442}443}444445public void add(E e) {446checkForComodification();447448try {449int i = cursor;450AbstractList.this.add(i, e);451lastRet = -1;452cursor = i + 1;453expectedModCount = modCount;454} catch (IndexOutOfBoundsException ex) {455throw new ConcurrentModificationException();456}457}458}459460/**461* {@inheritDoc}462*463* @implSpec464* This implementation returns a list that subclasses465* {@code AbstractList}. The subclass stores, in private fields, the466* size of the subList (which can change over its lifetime), and the467* expected {@code modCount} value of the backing list. There are two468* variants of the subclass, one of which implements {@code RandomAccess}.469* If this list implements {@code RandomAccess} the returned list will470* be an instance of the subclass that implements {@code RandomAccess}.471*472* <p>The subclass's {@code set(int, E)}, {@code get(int)},473* {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,474* Collection)} and {@code removeRange(int, int)} methods all475* delegate to the corresponding methods on the backing abstract list,476* after bounds-checking the index and adjusting for the offset. The477* {@code addAll(Collection c)} method merely returns {@code addAll(size,478* c)}.479*480* <p>The {@code listIterator(int)} method returns a "wrapper object"481* over a list iterator on the backing list, which is created with the482* corresponding method on the backing list. The {@code iterator} method483* merely returns {@code listIterator()}, and the {@code size} method484* merely returns the subclass's {@code size} field.485*486* <p>All methods first check to see if the actual {@code modCount} of487* the backing list is equal to its expected value, and throw a488* {@code ConcurrentModificationException} if it is not.489*490* @throws IndexOutOfBoundsException if an endpoint index value is out of range491* {@code (fromIndex < 0 || toIndex > size)}492* @throws IllegalArgumentException if the endpoint indices are out of order493* {@code (fromIndex > toIndex)}494*/495public List<E> subList(int fromIndex, int toIndex) {496subListRangeCheck(fromIndex, toIndex, size());497return (this instanceof RandomAccess ?498new RandomAccessSubList<>(this, fromIndex, toIndex) :499new SubList<>(this, fromIndex, toIndex));500}501502static void subListRangeCheck(int fromIndex, int toIndex, int size) {503if (fromIndex < 0)504throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);505if (toIndex > size)506throw new IndexOutOfBoundsException("toIndex = " + toIndex);507if (fromIndex > toIndex)508throw new IllegalArgumentException("fromIndex(" + fromIndex +509") > toIndex(" + toIndex + ")");510}511512// Comparison and hashing513514/**515* Compares the specified object with this list for equality. Returns516* {@code true} if and only if the specified object is also a list, both517* lists have the same size, and all corresponding pairs of elements in518* the two lists are <i>equal</i>. (Two elements {@code e1} and519* {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null :520* e1.equals(e2))}.) In other words, two lists are defined to be521* equal if they contain the same elements in the same order.522*523* @implSpec524* This implementation first checks if the specified object is this525* list. If so, it returns {@code true}; if not, it checks if the526* specified object is a list. If not, it returns {@code false}; if so,527* it iterates over both lists, comparing corresponding pairs of elements.528* If any comparison returns {@code false}, this method returns529* {@code false}. If either iterator runs out of elements before the530* other it returns {@code false} (as the lists are of unequal length);531* otherwise it returns {@code true} when the iterations complete.532*533* @param o the object to be compared for equality with this list534* @return {@code true} if the specified object is equal to this list535*/536public boolean equals(Object o) {537if (o == this)538return true;539if (!(o instanceof List))540return false;541542ListIterator<E> e1 = listIterator();543ListIterator<?> e2 = ((List<?>) o).listIterator();544while (e1.hasNext() && e2.hasNext()) {545E o1 = e1.next();546Object o2 = e2.next();547if (!(o1==null ? o2==null : o1.equals(o2)))548return false;549}550return !(e1.hasNext() || e2.hasNext());551}552553/**554* Returns the hash code value for this list.555*556* @implSpec557* This implementation uses exactly the code that is used to define the558* list hash function in the documentation for the {@link List#hashCode}559* method.560*561* @return the hash code value for this list562*/563public int hashCode() {564int hashCode = 1;565for (E e : this)566hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());567return hashCode;568}569570/**571* Removes from this list all of the elements whose index is between572* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.573* Shifts any succeeding elements to the left (reduces their index).574* This call shortens the list by {@code (toIndex - fromIndex)} elements.575* (If {@code toIndex==fromIndex}, this operation has no effect.)576*577* <p>This method is called by the {@code clear} operation on this list578* and its subLists. Overriding this method to take advantage of579* the internals of the list implementation can <i>substantially</i>580* improve the performance of the {@code clear} operation on this list581* and its subLists.582*583* @implSpec584* This implementation gets a list iterator positioned before585* {@code fromIndex}, and repeatedly calls {@code ListIterator.next}586* followed by {@code ListIterator.remove} until the entire range has587* been removed. <b>Note: if {@code ListIterator.remove} requires linear588* time, this implementation requires quadratic time.</b>589*590* @param fromIndex index of first element to be removed591* @param toIndex index after last element to be removed592*/593protected void removeRange(int fromIndex, int toIndex) {594ListIterator<E> it = listIterator(fromIndex);595for (int i=0, n=toIndex-fromIndex; i<n; i++) {596it.next();597it.remove();598}599}600601/**602* The number of times this list has been <i>structurally modified</i>.603* Structural modifications are those that change the size of the604* list, or otherwise perturb it in such a fashion that iterations in605* progress may yield incorrect results.606*607* <p>This field is used by the iterator and list iterator implementation608* returned by the {@code iterator} and {@code listIterator} methods.609* If the value of this field changes unexpectedly, the iterator (or list610* iterator) will throw a {@code ConcurrentModificationException} in611* response to the {@code next}, {@code remove}, {@code previous},612* {@code set} or {@code add} operations. This provides613* <i>fail-fast</i> behavior, rather than non-deterministic behavior in614* the face of concurrent modification during iteration.615*616* <p><b>Use of this field by subclasses is optional.</b> If a subclass617* wishes to provide fail-fast iterators (and list iterators), then it618* merely has to increment this field in its {@code add(int, E)} and619* {@code remove(int)} methods (and any other methods that it overrides620* that result in structural modifications to the list). A single call to621* {@code add(int, E)} or {@code remove(int)} must add no more than622* one to this field, or the iterators (and list iterators) will throw623* bogus {@code ConcurrentModificationExceptions}. If an implementation624* does not wish to provide fail-fast iterators, this field may be625* ignored.626*/627protected transient int modCount = 0;628629private void rangeCheckForAdd(int index) {630if (index < 0 || index > size())631throw new IndexOutOfBoundsException(outOfBoundsMsg(index));632}633634private String outOfBoundsMsg(int index) {635return "Index: "+index+", Size: "+size();636}637638/**639* An index-based split-by-two, lazily initialized Spliterator covering640* a List that access elements via {@link List#get}.641*642* If access results in an IndexOutOfBoundsException then a643* ConcurrentModificationException is thrown instead (since the list has644* been structurally modified while traversing).645*646* If the List is an instance of AbstractList then concurrent modification647* checking is performed using the AbstractList's modCount field.648*/649static final class RandomAccessSpliterator<E> implements Spliterator<E> {650651private final List<E> list;652private int index; // current index, modified on advance/split653private int fence; // -1 until used; then one past last index654655// The following fields are valid if covering an AbstractList656private final AbstractList<E> alist;657private int expectedModCount; // initialized when fence set658659RandomAccessSpliterator(List<E> list) {660assert list instanceof RandomAccess;661662this.list = list;663this.index = 0;664this.fence = -1;665666this.alist = list instanceof AbstractList ? (AbstractList<E>) list : null;667this.expectedModCount = alist != null ? alist.modCount : 0;668}669670/** Create new spliterator covering the given range */671private RandomAccessSpliterator(RandomAccessSpliterator<E> parent,672int origin, int fence) {673this.list = parent.list;674this.index = origin;675this.fence = fence;676677this.alist = parent.alist;678this.expectedModCount = parent.expectedModCount;679}680681private int getFence() { // initialize fence to size on first use682int hi;683List<E> lst = list;684if ((hi = fence) < 0) {685if (alist != null) {686expectedModCount = alist.modCount;687}688hi = fence = lst.size();689}690return hi;691}692693public Spliterator<E> trySplit() {694int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;695return (lo >= mid) ? null : // divide range in half unless too small696new RandomAccessSpliterator<>(this, lo, index = mid);697}698699public boolean tryAdvance(Consumer<? super E> action) {700if (action == null)701throw new NullPointerException();702int hi = getFence(), i = index;703if (i < hi) {704index = i + 1;705action.accept(get(list, i));706checkAbstractListModCount(alist, expectedModCount);707return true;708}709return false;710}711712public void forEachRemaining(Consumer<? super E> action) {713Objects.requireNonNull(action);714List<E> lst = list;715int hi = getFence();716int i = index;717index = hi;718for (; i < hi; i++) {719action.accept(get(lst, i));720}721checkAbstractListModCount(alist, expectedModCount);722}723724public long estimateSize() {725return (long) (getFence() - index);726}727728public int characteristics() {729return Spliterator.ORDERED | Spliterator.SIZED | Spliterator.SUBSIZED;730}731732private static <E> E get(List<E> list, int i) {733try {734return list.get(i);735} catch (IndexOutOfBoundsException ex) {736throw new ConcurrentModificationException();737}738}739740static void checkAbstractListModCount(AbstractList<?> alist, int expectedModCount) {741if (alist != null && alist.modCount != expectedModCount) {742throw new ConcurrentModificationException();743}744}745}746747private static class SubList<E> extends AbstractList<E> {748private final AbstractList<E> root;749private final SubList<E> parent;750private final int offset;751protected int size;752753/**754* Constructs a sublist of an arbitrary AbstractList, which is755* not a SubList itself.756*/757public SubList(AbstractList<E> root, int fromIndex, int toIndex) {758this.root = root;759this.parent = null;760this.offset = fromIndex;761this.size = toIndex - fromIndex;762this.modCount = root.modCount;763}764765/**766* Constructs a sublist of another SubList.767*/768protected SubList(SubList<E> parent, int fromIndex, int toIndex) {769this.root = parent.root;770this.parent = parent;771this.offset = parent.offset + fromIndex;772this.size = toIndex - fromIndex;773this.modCount = root.modCount;774}775776public E set(int index, E element) {777Objects.checkIndex(index, size);778checkForComodification();779return root.set(offset + index, element);780}781782public E get(int index) {783Objects.checkIndex(index, size);784checkForComodification();785return root.get(offset + index);786}787788public int size() {789checkForComodification();790return size;791}792793public void add(int index, E element) {794rangeCheckForAdd(index);795checkForComodification();796root.add(offset + index, element);797updateSizeAndModCount(1);798}799800public E remove(int index) {801Objects.checkIndex(index, size);802checkForComodification();803E result = root.remove(offset + index);804updateSizeAndModCount(-1);805return result;806}807808protected void removeRange(int fromIndex, int toIndex) {809checkForComodification();810root.removeRange(offset + fromIndex, offset + toIndex);811updateSizeAndModCount(fromIndex - toIndex);812}813814public boolean addAll(Collection<? extends E> c) {815return addAll(size, c);816}817818public boolean addAll(int index, Collection<? extends E> c) {819rangeCheckForAdd(index);820int cSize = c.size();821if (cSize==0)822return false;823checkForComodification();824root.addAll(offset + index, c);825updateSizeAndModCount(cSize);826return true;827}828829public Iterator<E> iterator() {830return listIterator();831}832833public ListIterator<E> listIterator(int index) {834checkForComodification();835rangeCheckForAdd(index);836837return new ListIterator<E>() {838private final ListIterator<E> i =839root.listIterator(offset + index);840841public boolean hasNext() {842return nextIndex() < size;843}844845public E next() {846if (hasNext())847return i.next();848else849throw new NoSuchElementException();850}851852public boolean hasPrevious() {853return previousIndex() >= 0;854}855856public E previous() {857if (hasPrevious())858return i.previous();859else860throw new NoSuchElementException();861}862863public int nextIndex() {864return i.nextIndex() - offset;865}866867public int previousIndex() {868return i.previousIndex() - offset;869}870871public void remove() {872i.remove();873updateSizeAndModCount(-1);874}875876public void set(E e) {877i.set(e);878}879880public void add(E e) {881i.add(e);882updateSizeAndModCount(1);883}884};885}886887public List<E> subList(int fromIndex, int toIndex) {888subListRangeCheck(fromIndex, toIndex, size);889return new SubList<>(this, fromIndex, toIndex);890}891892private void rangeCheckForAdd(int index) {893if (index < 0 || index > size)894throw new IndexOutOfBoundsException(outOfBoundsMsg(index));895}896897private String outOfBoundsMsg(int index) {898return "Index: "+index+", Size: "+size;899}900901private void checkForComodification() {902if (root.modCount != this.modCount)903throw new ConcurrentModificationException();904}905906private void updateSizeAndModCount(int sizeChange) {907SubList<E> slist = this;908do {909slist.size += sizeChange;910slist.modCount = root.modCount;911slist = slist.parent;912} while (slist != null);913}914}915916private static class RandomAccessSubList<E>917extends SubList<E> implements RandomAccess {918919/**920* Constructs a sublist of an arbitrary AbstractList, which is921* not a RandomAccessSubList itself.922*/923RandomAccessSubList(AbstractList<E> root,924int fromIndex, int toIndex) {925super(root, fromIndex, toIndex);926}927928/**929* Constructs a sublist of another RandomAccessSubList.930*/931RandomAccessSubList(RandomAccessSubList<E> parent,932int fromIndex, int toIndex) {933super(parent, fromIndex, toIndex);934}935936public List<E> subList(int fromIndex, int toIndex) {937subListRangeCheck(fromIndex, toIndex, size);938return new RandomAccessSubList<>(this, fromIndex, toIndex);939}940}941}942943944