Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/share/classes/java/util/AbstractList.java
38829 views
/*1* Copyright (c) 1997, 2012, 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;2627/**28* This class provides a skeletal implementation of the {@link List}29* interface to minimize the effort required to implement this interface30* backed by a "random access" data store (such as an array). For sequential31* access data (such as a linked list), {@link AbstractSequentialList} should32* be used in preference to this class.33*34* <p>To implement an unmodifiable list, the programmer needs only to extend35* this class and provide implementations for the {@link #get(int)} and36* {@link List#size() size()} methods.37*38* <p>To implement a modifiable list, the programmer must additionally39* override the {@link #set(int, Object) set(int, E)} method (which otherwise40* throws an {@code UnsupportedOperationException}). If the list is41* variable-size the programmer must additionally override the42* {@link #add(int, Object) add(int, E)} and {@link #remove(int)} methods.43*44* <p>The programmer should generally provide a void (no argument) and collection45* constructor, as per the recommendation in the {@link Collection} interface46* specification.47*48* <p>Unlike the other abstract collection implementations, the programmer does49* <i>not</i> have to provide an iterator implementation; the iterator and50* list iterator are implemented by this class, on top of the "random access"51* methods:52* {@link #get(int)},53* {@link #set(int, Object) set(int, E)},54* {@link #add(int, Object) add(int, E)} and55* {@link #remove(int)}.56*57* <p>The documentation for each non-abstract method in this class describes its58* implementation in detail. Each of these methods may be overridden if the59* collection being implemented admits a more efficient implementation.60*61* <p>This class is a member of the62* <a href="{@docRoot}/../technotes/guides/collections/index.html">63* Java Collections Framework</a>.64*65* @author Josh Bloch66* @author Neal Gafter67* @since 1.268*/6970public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {71/**72* Sole constructor. (For invocation by subclass constructors, typically73* implicit.)74*/75protected AbstractList() {76}7778/**79* Appends the specified element to the end of this list (optional80* operation).81*82* <p>Lists that support this operation may place limitations on what83* elements may be added to this list. In particular, some84* lists will refuse to add null elements, and others will impose85* restrictions on the type of elements that may be added. List86* classes should clearly specify in their documentation any restrictions87* on what elements may be added.88*89* <p>This implementation calls {@code add(size(), e)}.90*91* <p>Note that this implementation throws an92* {@code UnsupportedOperationException} unless93* {@link #add(int, Object) add(int, E)} is overridden.94*95* @param e element to be appended to this list96* @return {@code true} (as specified by {@link Collection#add})97* @throws UnsupportedOperationException if the {@code add} operation98* is not supported by this list99* @throws ClassCastException if the class of the specified element100* prevents it from being added to this list101* @throws NullPointerException if the specified element is null and this102* list does not permit null elements103* @throws IllegalArgumentException if some property of this element104* prevents it from being added to this list105*/106public boolean add(E e) {107add(size(), e);108return true;109}110111/**112* {@inheritDoc}113*114* @throws IndexOutOfBoundsException {@inheritDoc}115*/116abstract public E get(int index);117118/**119* {@inheritDoc}120*121* <p>This implementation always throws an122* {@code UnsupportedOperationException}.123*124* @throws UnsupportedOperationException {@inheritDoc}125* @throws ClassCastException {@inheritDoc}126* @throws NullPointerException {@inheritDoc}127* @throws IllegalArgumentException {@inheritDoc}128* @throws IndexOutOfBoundsException {@inheritDoc}129*/130public E set(int index, E element) {131throw new UnsupportedOperationException();132}133134/**135* {@inheritDoc}136*137* <p>This implementation always throws an138* {@code UnsupportedOperationException}.139*140* @throws UnsupportedOperationException {@inheritDoc}141* @throws ClassCastException {@inheritDoc}142* @throws NullPointerException {@inheritDoc}143* @throws IllegalArgumentException {@inheritDoc}144* @throws IndexOutOfBoundsException {@inheritDoc}145*/146public void add(int index, E element) {147throw new UnsupportedOperationException();148}149150/**151* {@inheritDoc}152*153* <p>This implementation always throws an154* {@code UnsupportedOperationException}.155*156* @throws UnsupportedOperationException {@inheritDoc}157* @throws IndexOutOfBoundsException {@inheritDoc}158*/159public E remove(int index) {160throw new UnsupportedOperationException();161}162163164// Search Operations165166/**167* {@inheritDoc}168*169* <p>This implementation first gets a list iterator (with170* {@code listIterator()}). Then, it iterates over the list until the171* specified element is found or the end of the list is reached.172*173* @throws ClassCastException {@inheritDoc}174* @throws NullPointerException {@inheritDoc}175*/176public int indexOf(Object o) {177ListIterator<E> it = listIterator();178if (o==null) {179while (it.hasNext())180if (it.next()==null)181return it.previousIndex();182} else {183while (it.hasNext())184if (o.equals(it.next()))185return it.previousIndex();186}187return -1;188}189190/**191* {@inheritDoc}192*193* <p>This implementation first gets a list iterator that points to the end194* of the list (with {@code listIterator(size())}). Then, it iterates195* backwards over the list until the specified element is found, or the196* beginning of the list is reached.197*198* @throws ClassCastException {@inheritDoc}199* @throws NullPointerException {@inheritDoc}200*/201public int lastIndexOf(Object o) {202ListIterator<E> it = listIterator(size());203if (o==null) {204while (it.hasPrevious())205if (it.previous()==null)206return it.nextIndex();207} else {208while (it.hasPrevious())209if (o.equals(it.previous()))210return it.nextIndex();211}212return -1;213}214215216// Bulk Operations217218/**219* Removes all of the elements from this list (optional operation).220* The list will be empty after this call returns.221*222* <p>This implementation calls {@code removeRange(0, size())}.223*224* <p>Note that this implementation throws an225* {@code UnsupportedOperationException} unless {@code remove(int226* index)} or {@code removeRange(int fromIndex, int toIndex)} is227* overridden.228*229* @throws UnsupportedOperationException if the {@code clear} operation230* is not supported by this list231*/232public void clear() {233removeRange(0, size());234}235236/**237* {@inheritDoc}238*239* <p>This implementation gets an iterator over the specified collection240* and iterates over it, inserting the elements obtained from the241* iterator into this list at the appropriate position, one at a time,242* using {@code add(int, E)}.243* Many implementations will override this method for efficiency.244*245* <p>Note that this implementation throws an246* {@code UnsupportedOperationException} unless247* {@link #add(int, Object) add(int, E)} is overridden.248*249* @throws UnsupportedOperationException {@inheritDoc}250* @throws ClassCastException {@inheritDoc}251* @throws NullPointerException {@inheritDoc}252* @throws IllegalArgumentException {@inheritDoc}253* @throws IndexOutOfBoundsException {@inheritDoc}254*/255public boolean addAll(int index, Collection<? extends E> c) {256rangeCheckForAdd(index);257boolean modified = false;258for (E e : c) {259add(index++, e);260modified = true;261}262return modified;263}264265266// Iterators267268/**269* Returns an iterator over the elements in this list in proper sequence.270*271* <p>This implementation returns a straightforward implementation of the272* iterator interface, relying on the backing list's {@code size()},273* {@code get(int)}, and {@code remove(int)} methods.274*275* <p>Note that the iterator returned by this method will throw an276* {@link UnsupportedOperationException} in response to its277* {@code remove} method unless the list's {@code remove(int)} method is278* overridden.279*280* <p>This implementation can be made to throw runtime exceptions in the281* face of concurrent modification, as described in the specification282* for the (protected) {@link #modCount} field.283*284* @return an iterator over the elements in this list in proper sequence285*/286public Iterator<E> iterator() {287return new Itr();288}289290/**291* {@inheritDoc}292*293* <p>This implementation returns {@code listIterator(0)}.294*295* @see #listIterator(int)296*/297public ListIterator<E> listIterator() {298return listIterator(0);299}300301/**302* {@inheritDoc}303*304* <p>This implementation returns a straightforward implementation of the305* {@code ListIterator} interface that extends the implementation of the306* {@code Iterator} interface returned by the {@code iterator()} method.307* The {@code ListIterator} implementation relies on the backing list's308* {@code get(int)}, {@code set(int, E)}, {@code add(int, E)}309* and {@code remove(int)} methods.310*311* <p>Note that the list iterator returned by this implementation will312* throw an {@link UnsupportedOperationException} in response to its313* {@code remove}, {@code set} and {@code add} methods unless the314* list's {@code remove(int)}, {@code set(int, E)}, and315* {@code add(int, E)} methods are overridden.316*317* <p>This implementation can be made to throw runtime exceptions in the318* face of concurrent modification, as described in the specification for319* the (protected) {@link #modCount} field.320*321* @throws IndexOutOfBoundsException {@inheritDoc}322*/323public ListIterator<E> listIterator(final int index) {324rangeCheckForAdd(index);325326return new ListItr(index);327}328329private class Itr implements Iterator<E> {330/**331* Index of element to be returned by subsequent call to next.332*/333int cursor = 0;334335/**336* Index of element returned by most recent call to next or337* previous. Reset to -1 if this element is deleted by a call338* to remove.339*/340int lastRet = -1;341342/**343* The modCount value that the iterator believes that the backing344* List should have. If this expectation is violated, the iterator345* has detected concurrent modification.346*/347int expectedModCount = modCount;348349public boolean hasNext() {350return cursor != size();351}352353public E next() {354checkForComodification();355try {356int i = cursor;357E next = get(i);358lastRet = i;359cursor = i + 1;360return next;361} catch (IndexOutOfBoundsException e) {362checkForComodification();363throw new NoSuchElementException();364}365}366367public void remove() {368if (lastRet < 0)369throw new IllegalStateException();370checkForComodification();371372try {373AbstractList.this.remove(lastRet);374if (lastRet < cursor)375cursor--;376lastRet = -1;377expectedModCount = modCount;378} catch (IndexOutOfBoundsException e) {379throw new ConcurrentModificationException();380}381}382383final void checkForComodification() {384if (modCount != expectedModCount)385throw new ConcurrentModificationException();386}387}388389private class ListItr extends Itr implements ListIterator<E> {390ListItr(int index) {391cursor = index;392}393394public boolean hasPrevious() {395return cursor != 0;396}397398public E previous() {399checkForComodification();400try {401int i = cursor - 1;402E previous = get(i);403lastRet = cursor = i;404return previous;405} catch (IndexOutOfBoundsException e) {406checkForComodification();407throw new NoSuchElementException();408}409}410411public int nextIndex() {412return cursor;413}414415public int previousIndex() {416return cursor-1;417}418419public void set(E e) {420if (lastRet < 0)421throw new IllegalStateException();422checkForComodification();423424try {425AbstractList.this.set(lastRet, e);426expectedModCount = modCount;427} catch (IndexOutOfBoundsException ex) {428throw new ConcurrentModificationException();429}430}431432public void add(E e) {433checkForComodification();434435try {436int i = cursor;437AbstractList.this.add(i, e);438lastRet = -1;439cursor = i + 1;440expectedModCount = modCount;441} catch (IndexOutOfBoundsException ex) {442throw new ConcurrentModificationException();443}444}445}446447/**448* {@inheritDoc}449*450* <p>This implementation returns a list that subclasses451* {@code AbstractList}. The subclass stores, in private fields, the452* offset of the subList within the backing list, the size of the subList453* (which can change over its lifetime), and the expected454* {@code modCount} value of the backing list. There are two variants455* of the subclass, one of which implements {@code RandomAccess}.456* If this list implements {@code RandomAccess} the returned list will457* be an instance of the subclass that implements {@code RandomAccess}.458*459* <p>The subclass's {@code set(int, E)}, {@code get(int)},460* {@code add(int, E)}, {@code remove(int)}, {@code addAll(int,461* Collection)} and {@code removeRange(int, int)} methods all462* delegate to the corresponding methods on the backing abstract list,463* after bounds-checking the index and adjusting for the offset. The464* {@code addAll(Collection c)} method merely returns {@code addAll(size,465* c)}.466*467* <p>The {@code listIterator(int)} method returns a "wrapper object"468* over a list iterator on the backing list, which is created with the469* corresponding method on the backing list. The {@code iterator} method470* merely returns {@code listIterator()}, and the {@code size} method471* merely returns the subclass's {@code size} field.472*473* <p>All methods first check to see if the actual {@code modCount} of474* the backing list is equal to its expected value, and throw a475* {@code ConcurrentModificationException} if it is not.476*477* @throws IndexOutOfBoundsException if an endpoint index value is out of range478* {@code (fromIndex < 0 || toIndex > size)}479* @throws IllegalArgumentException if the endpoint indices are out of order480* {@code (fromIndex > toIndex)}481*/482public List<E> subList(int fromIndex, int toIndex) {483return (this instanceof RandomAccess ?484new RandomAccessSubList<>(this, fromIndex, toIndex) :485new SubList<>(this, fromIndex, toIndex));486}487488// Comparison and hashing489490/**491* Compares the specified object with this list for equality. Returns492* {@code true} if and only if the specified object is also a list, both493* lists have the same size, and all corresponding pairs of elements in494* the two lists are <i>equal</i>. (Two elements {@code e1} and495* {@code e2} are <i>equal</i> if {@code (e1==null ? e2==null :496* e1.equals(e2))}.) In other words, two lists are defined to be497* equal if they contain the same elements in the same order.<p>498*499* This implementation first checks if the specified object is this500* list. If so, it returns {@code true}; if not, it checks if the501* specified object is a list. If not, it returns {@code false}; if so,502* it iterates over both lists, comparing corresponding pairs of elements.503* If any comparison returns {@code false}, this method returns504* {@code false}. If either iterator runs out of elements before the505* other it returns {@code false} (as the lists are of unequal length);506* otherwise it returns {@code true} when the iterations complete.507*508* @param o the object to be compared for equality with this list509* @return {@code true} if the specified object is equal to this list510*/511public boolean equals(Object o) {512if (o == this)513return true;514if (!(o instanceof List))515return false;516517ListIterator<E> e1 = listIterator();518ListIterator<?> e2 = ((List<?>) o).listIterator();519while (e1.hasNext() && e2.hasNext()) {520E o1 = e1.next();521Object o2 = e2.next();522if (!(o1==null ? o2==null : o1.equals(o2)))523return false;524}525return !(e1.hasNext() || e2.hasNext());526}527528/**529* Returns the hash code value for this list.530*531* <p>This implementation uses exactly the code that is used to define the532* list hash function in the documentation for the {@link List#hashCode}533* method.534*535* @return the hash code value for this list536*/537public int hashCode() {538int hashCode = 1;539for (E e : this)540hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());541return hashCode;542}543544/**545* Removes from this list all of the elements whose index is between546* {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.547* Shifts any succeeding elements to the left (reduces their index).548* This call shortens the list by {@code (toIndex - fromIndex)} elements.549* (If {@code toIndex==fromIndex}, this operation has no effect.)550*551* <p>This method is called by the {@code clear} operation on this list552* and its subLists. Overriding this method to take advantage of553* the internals of the list implementation can <i>substantially</i>554* improve the performance of the {@code clear} operation on this list555* and its subLists.556*557* <p>This implementation gets a list iterator positioned before558* {@code fromIndex}, and repeatedly calls {@code ListIterator.next}559* followed by {@code ListIterator.remove} until the entire range has560* been removed. <b>Note: if {@code ListIterator.remove} requires linear561* time, this implementation requires quadratic time.</b>562*563* @param fromIndex index of first element to be removed564* @param toIndex index after last element to be removed565*/566protected void removeRange(int fromIndex, int toIndex) {567ListIterator<E> it = listIterator(fromIndex);568for (int i=0, n=toIndex-fromIndex; i<n; i++) {569it.next();570it.remove();571}572}573574/**575* The number of times this list has been <i>structurally modified</i>.576* Structural modifications are those that change the size of the577* list, or otherwise perturb it in such a fashion that iterations in578* progress may yield incorrect results.579*580* <p>This field is used by the iterator and list iterator implementation581* returned by the {@code iterator} and {@code listIterator} methods.582* If the value of this field changes unexpectedly, the iterator (or list583* iterator) will throw a {@code ConcurrentModificationException} in584* response to the {@code next}, {@code remove}, {@code previous},585* {@code set} or {@code add} operations. This provides586* <i>fail-fast</i> behavior, rather than non-deterministic behavior in587* the face of concurrent modification during iteration.588*589* <p><b>Use of this field by subclasses is optional.</b> If a subclass590* wishes to provide fail-fast iterators (and list iterators), then it591* merely has to increment this field in its {@code add(int, E)} and592* {@code remove(int)} methods (and any other methods that it overrides593* that result in structural modifications to the list). A single call to594* {@code add(int, E)} or {@code remove(int)} must add no more than595* one to this field, or the iterators (and list iterators) will throw596* bogus {@code ConcurrentModificationExceptions}. If an implementation597* does not wish to provide fail-fast iterators, this field may be598* ignored.599*/600protected transient int modCount = 0;601602private void rangeCheckForAdd(int index) {603if (index < 0 || index > size())604throw new IndexOutOfBoundsException(outOfBoundsMsg(index));605}606607private String outOfBoundsMsg(int index) {608return "Index: "+index+", Size: "+size();609}610}611612class SubList<E> extends AbstractList<E> {613private final AbstractList<E> l;614private final int offset;615private int size;616617SubList(AbstractList<E> list, int fromIndex, int toIndex) {618if (fromIndex < 0)619throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);620if (toIndex > list.size())621throw new IndexOutOfBoundsException("toIndex = " + toIndex);622if (fromIndex > toIndex)623throw new IllegalArgumentException("fromIndex(" + fromIndex +624") > toIndex(" + toIndex + ")");625l = list;626offset = fromIndex;627size = toIndex - fromIndex;628this.modCount = l.modCount;629}630631public E set(int index, E element) {632rangeCheck(index);633checkForComodification();634return l.set(index+offset, element);635}636637public E get(int index) {638rangeCheck(index);639checkForComodification();640return l.get(index+offset);641}642643public int size() {644checkForComodification();645return size;646}647648public void add(int index, E element) {649rangeCheckForAdd(index);650checkForComodification();651l.add(index+offset, element);652this.modCount = l.modCount;653size++;654}655656public E remove(int index) {657rangeCheck(index);658checkForComodification();659E result = l.remove(index+offset);660this.modCount = l.modCount;661size--;662return result;663}664665protected void removeRange(int fromIndex, int toIndex) {666checkForComodification();667l.removeRange(fromIndex+offset, toIndex+offset);668this.modCount = l.modCount;669size -= (toIndex-fromIndex);670}671672public boolean addAll(Collection<? extends E> c) {673return addAll(size, c);674}675676public boolean addAll(int index, Collection<? extends E> c) {677rangeCheckForAdd(index);678int cSize = c.size();679if (cSize==0)680return false;681682checkForComodification();683l.addAll(offset+index, c);684this.modCount = l.modCount;685size += cSize;686return true;687}688689public Iterator<E> iterator() {690return listIterator();691}692693public ListIterator<E> listIterator(final int index) {694checkForComodification();695rangeCheckForAdd(index);696697return new ListIterator<E>() {698private final ListIterator<E> i = l.listIterator(index+offset);699700public boolean hasNext() {701return nextIndex() < size;702}703704public E next() {705if (hasNext())706return i.next();707else708throw new NoSuchElementException();709}710711public boolean hasPrevious() {712return previousIndex() >= 0;713}714715public E previous() {716if (hasPrevious())717return i.previous();718else719throw new NoSuchElementException();720}721722public int nextIndex() {723return i.nextIndex() - offset;724}725726public int previousIndex() {727return i.previousIndex() - offset;728}729730public void remove() {731i.remove();732SubList.this.modCount = l.modCount;733size--;734}735736public void set(E e) {737i.set(e);738}739740public void add(E e) {741i.add(e);742SubList.this.modCount = l.modCount;743size++;744}745};746}747748public List<E> subList(int fromIndex, int toIndex) {749return new SubList<>(this, fromIndex, toIndex);750}751752private void rangeCheck(int index) {753if (index < 0 || index >= size)754throw new IndexOutOfBoundsException(outOfBoundsMsg(index));755}756757private void rangeCheckForAdd(int index) {758if (index < 0 || index > size)759throw new IndexOutOfBoundsException(outOfBoundsMsg(index));760}761762private String outOfBoundsMsg(int index) {763return "Index: "+index+", Size: "+size;764}765766private void checkForComodification() {767if (this.modCount != l.modCount)768throw new ConcurrentModificationException();769}770}771772class RandomAccessSubList<E> extends SubList<E> implements RandomAccess {773RandomAccessSubList(AbstractList<E> list, int fromIndex, int toIndex) {774super(list, fromIndex, toIndex);775}776777public List<E> subList(int fromIndex, int toIndex) {778return new RandomAccessSubList<>(this, fromIndex, toIndex);779}780}781782783