1 /*
2  * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.util;
27 
28 /**
29  * This class provides a skeletal implementation of the {@code List}
30  * interface to minimize the effort required to implement this interface
31  * backed by a "sequential access" data store (such as a linked list).  For
32  * random access data (such as an array), {@code AbstractList} should be used
33  * in preference to this class.<p>
34  *
35  * This class is the opposite of the {@code AbstractList} class in the sense
36  * that it implements the "random access" methods ({@code get(int index)},
37  * {@code set(int index, E element)}, {@code add(int index, E element)} and
38  * {@code remove(int index)}) on top of the list's list iterator, instead of
39  * the other way around.<p>
40  *
41  * To implement a list the programmer needs only to extend this class and
42  * provide implementations for the {@code listIterator} and {@code size}
43  * methods.  For an unmodifiable list, the programmer need only implement the
44  * list iterator's {@code hasNext}, {@code next}, {@code hasPrevious},
45  * {@code previous} and {@code index} methods.<p>
46  *
47  * For a modifiable list the programmer should additionally implement the list
48  * iterator's {@code set} method.  For a variable-size list the programmer
49  * should additionally implement the list iterator's {@code remove} and
50  * {@code add} methods.<p>
51  *
52  * The programmer should generally provide a void (no argument) and collection
53  * constructor, as per the recommendation in the {@code Collection} interface
54  * specification.<p>
55  *
56  * This class is a member of the
57  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
58  * Java Collections Framework</a>.
59  *
60  * @param <E> the type of elements in this list
61  *
62  * @author  Josh Bloch
63  * @author  Neal Gafter
64  * @see Collection
65  * @see List
66  * @see AbstractList
67  * @see AbstractCollection
68  * @since 1.2
69  */
70 
71 public abstract class AbstractSequentialList<E> extends AbstractList<E> {
72     /**
73      * Sole constructor.  (For invocation by subclass constructors, typically
74      * implicit.)
75      */
AbstractSequentialList()76     protected AbstractSequentialList() {
77     }
78 
79     /**
80      * Returns the element at the specified position in this list.
81      *
82      * <p>This implementation first gets a list iterator pointing to the
83      * indexed element (with {@code listIterator(index)}).  Then, it gets
84      * the element using {@code ListIterator.next} and returns it.
85      *
86      * @throws IndexOutOfBoundsException {@inheritDoc}
87      */
get(int index)88     public E get(int index) {
89         try {
90             return listIterator(index).next();
91         } catch (NoSuchElementException exc) {
92             throw new IndexOutOfBoundsException("Index: "+index);
93         }
94     }
95 
96     /**
97      * Replaces the element at the specified position in this list with the
98      * specified element (optional operation).
99      *
100      * <p>This implementation first gets a list iterator pointing to the
101      * indexed element (with {@code listIterator(index)}).  Then, it gets
102      * the current element using {@code ListIterator.next} and replaces it
103      * with {@code ListIterator.set}.
104      *
105      * <p>Note that this implementation will throw an
106      * {@code UnsupportedOperationException} if the list iterator does not
107      * implement the {@code set} operation.
108      *
109      * @throws UnsupportedOperationException {@inheritDoc}
110      * @throws ClassCastException            {@inheritDoc}
111      * @throws NullPointerException          {@inheritDoc}
112      * @throws IllegalArgumentException      {@inheritDoc}
113      * @throws IndexOutOfBoundsException     {@inheritDoc}
114      */
set(int index, E element)115     public E set(int index, E element) {
116         try {
117             ListIterator<E> e = listIterator(index);
118             E oldVal = e.next();
119             e.set(element);
120             return oldVal;
121         } catch (NoSuchElementException exc) {
122             throw new IndexOutOfBoundsException("Index: "+index);
123         }
124     }
125 
126     /**
127      * Inserts the specified element at the specified position in this list
128      * (optional operation).  Shifts the element currently at that position
129      * (if any) and any subsequent elements to the right (adds one to their
130      * indices).
131      *
132      * <p>This implementation first gets a list iterator pointing to the
133      * indexed element (with {@code listIterator(index)}).  Then, it
134      * inserts the specified element with {@code ListIterator.add}.
135      *
136      * <p>Note that this implementation will throw an
137      * {@code UnsupportedOperationException} if the list iterator does not
138      * implement the {@code add} operation.
139      *
140      * @throws UnsupportedOperationException {@inheritDoc}
141      * @throws ClassCastException            {@inheritDoc}
142      * @throws NullPointerException          {@inheritDoc}
143      * @throws IllegalArgumentException      {@inheritDoc}
144      * @throws IndexOutOfBoundsException     {@inheritDoc}
145      */
add(int index, E element)146     public void add(int index, E element) {
147         try {
148             listIterator(index).add(element);
149         } catch (NoSuchElementException exc) {
150             throw new IndexOutOfBoundsException("Index: "+index);
151         }
152     }
153 
154     /**
155      * Removes the element at the specified position in this list (optional
156      * operation).  Shifts any subsequent elements to the left (subtracts one
157      * from their indices).  Returns the element that was removed from the
158      * list.
159      *
160      * <p>This implementation first gets a list iterator pointing to the
161      * indexed element (with {@code listIterator(index)}).  Then, it removes
162      * the element with {@code ListIterator.remove}.
163      *
164      * <p>Note that this implementation will throw an
165      * {@code UnsupportedOperationException} if the list iterator does not
166      * implement the {@code remove} operation.
167      *
168      * @throws UnsupportedOperationException {@inheritDoc}
169      * @throws IndexOutOfBoundsException     {@inheritDoc}
170      */
remove(int index)171     public E remove(int index) {
172         try {
173             ListIterator<E> e = listIterator(index);
174             E outCast = e.next();
175             e.remove();
176             return outCast;
177         } catch (NoSuchElementException exc) {
178             throw new IndexOutOfBoundsException("Index: "+index);
179         }
180     }
181 
182 
183     // Bulk Operations
184 
185     /**
186      * Inserts all of the elements in the specified collection into this
187      * list at the specified position (optional operation).  Shifts the
188      * element currently at that position (if any) and any subsequent
189      * elements to the right (increases their indices).  The new elements
190      * will appear in this list in the order that they are returned by the
191      * specified collection's iterator.  The behavior of this operation is
192      * undefined if the specified collection is modified while the
193      * operation is in progress.  (Note that this will occur if the specified
194      * collection is this list, and it's nonempty.)
195      *
196      * <p>This implementation gets an iterator over the specified collection and
197      * a list iterator over this list pointing to the indexed element (with
198      * {@code listIterator(index)}).  Then, it iterates over the specified
199      * collection, inserting the elements obtained from the iterator into this
200      * list, one at a time, using {@code ListIterator.add} followed by
201      * {@code ListIterator.next} (to skip over the added element).
202      *
203      * <p>Note that this implementation will throw an
204      * {@code UnsupportedOperationException} if the list iterator returned by
205      * the {@code listIterator} method does not implement the {@code add}
206      * operation.
207      *
208      * @throws UnsupportedOperationException {@inheritDoc}
209      * @throws ClassCastException            {@inheritDoc}
210      * @throws NullPointerException          {@inheritDoc}
211      * @throws IllegalArgumentException      {@inheritDoc}
212      * @throws IndexOutOfBoundsException     {@inheritDoc}
213      */
addAll(int index, Collection<? extends E> c)214     public boolean addAll(int index, Collection<? extends E> c) {
215         try {
216             boolean modified = false;
217             ListIterator<E> e1 = listIterator(index);
218             for (E e : c) {
219                 e1.add(e);
220                 modified = true;
221             }
222             return modified;
223         } catch (NoSuchElementException exc) {
224             throw new IndexOutOfBoundsException("Index: "+index);
225         }
226     }
227 
228 
229     // Iterators
230 
231     /**
232      * Returns an iterator over the elements in this list (in proper
233      * sequence).<p>
234      *
235      * This implementation merely returns a list iterator over the list.
236      *
237      * @return an iterator over the elements in this list (in proper sequence)
238      */
iterator()239     public Iterator<E> iterator() {
240         return listIterator();
241     }
242 
243     /**
244      * Returns a list iterator over the elements in this list (in proper
245      * sequence).
246      *
247      * @param  index index of first element to be returned from the list
248      *         iterator (by a call to the {@code next} method)
249      * @return a list iterator over the elements in this list (in proper
250      *         sequence)
251      * @throws IndexOutOfBoundsException {@inheritDoc}
252      */
listIterator(int index)253     public abstract ListIterator<E> listIterator(int index);
254 }
255