1 /*
2  * Copyright (c) 2021, 2023, 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  * A collection that has a well-defined encounter order, that supports operations at both ends,
30  * and that is reversible. The elements of a sequenced collection have an <a id="encounter">
31  * <i>encounter order</i></a>, where conceptually the elements have a linear arrangement
32  * from the first element to the last element. Given any two elements, one element is
33  * either before (closer to the first element) or after (closer to the last element)
34  * the other element.
35  * <p>
36  * (Note that this definition does not imply anything about physical positioning
37  * of elements, such as their locations in a computer's memory.)
38  * <p>
39  * Several methods inherited from the {@link Collection} interface are required to operate
40  * on elements according to this collection's encounter order. For instance, the
41  * {@link Collection#iterator iterator} method provides elements starting from the first element,
42  * proceeding through successive elements, until the last element. Other methods that are
43  * required to operate on elements in encounter order include the following:
44  * {@link Iterable#forEach forEach}, {@link Collection#parallelStream parallelStream},
45  * {@link Collection#spliterator spliterator}, {@link Collection#stream stream},
46  * and all overloads of the {@link Collection#toArray toArray} method.
47  * <p>
48  * This interface provides methods to add, retrieve, and remove elements at either end
49  * of the collection.
50  * <p>
51  * This interface also defines the {@link #reversed reversed} method, which provides
52  * a reverse-ordered <a href="Collection.html#view">view</a> of this collection.
53  * In the reverse-ordered view, the concepts of first and last are inverted, as are
54  * the concepts of successor and predecessor. The first element of this collection is
55  * the last element of the reverse-ordered view, and vice-versa. The successor of some
56  * element in this collection is its predecessor in the reversed view, and vice-versa. All
57  * methods that respect the encounter order of the collection operate as if the encounter order
58  * is inverted. For instance, the {@link #iterator} method of the reversed view reports the
59  * elements in order from the last element of this collection to the first. The availability of
60  * the {@code reversed} method, and its impact on the ordering semantics of all applicable
61  * methods, allow convenient iteration, searching, copying, and streaming of the elements of
62  * this collection in either forward order or reverse order.
63  * <p>
64  * This class is a member of the
65  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
66  * Java Collections Framework</a>.
67  *
68  * @apiNote
69  * This interface does not impose any requirements on the {@code equals} and {@code hashCode}
70  * methods, because requirements imposed by sub-interfaces {@link List} and {@link SequencedSet}
71  * (which inherits requirements from {@link Set}) would be in conflict. See the specifications for
72  * {@link Collection#equals Collection.equals} and {@link Collection#hashCode Collection.hashCode}
73  * for further information.
74  *
75  * @param <E> the type of elements in this collection
76  * @since 21
77  */
78 public interface SequencedCollection<E> extends Collection<E> {
79     /**
80      * Returns a reverse-ordered <a href="Collection.html#view">view</a> of this collection.
81      * The encounter order of elements in the returned view is the inverse of the encounter
82      * order of elements in this collection. The reverse ordering affects all order-sensitive
83      * operations, including those on the view collections of the returned view. If the collection
84      * implementation permits modifications to this view, the modifications "write through" to the
85      * underlying collection. Changes to the underlying collection might or might not be visible
86      * in this reversed view, depending upon the implementation.
87      *
88      * @return a reverse-ordered view of this collection
89      */
reversed()90     SequencedCollection<E> reversed();
91 
92     /**
93      * Adds an element as the first element of this collection (optional operation).
94      * After this operation completes normally, the given element will be a member of
95      * this collection, and it will be the first element in encounter order.
96      *
97      * @implSpec
98      * The implementation in this interface always throws {@code UnsupportedOperationException}.
99      *
100      * @param e the element to be added
101      * @throws NullPointerException if the specified element is null and this
102      *         collection does not permit null elements
103      * @throws UnsupportedOperationException if this collection implementation
104      *         does not support this operation
105      */
addFirst(E e)106     default void addFirst(E e) {
107         throw new UnsupportedOperationException();
108     }
109 
110     /**
111      * Adds an element as the last element of this collection (optional operation).
112      * After this operation completes normally, the given element will be a member of
113      * this collection, and it will be the last element in encounter order.
114      *
115      * @implSpec
116      * The implementation in this interface always throws {@code UnsupportedOperationException}.
117      *
118      * @param e the element to be added.
119      * @throws NullPointerException if the specified element is null and this
120      *         collection does not permit null elements
121      * @throws UnsupportedOperationException if this collection implementation
122      *         does not support this operation
123      */
addLast(E e)124     default void addLast(E e) {
125         throw new UnsupportedOperationException();
126     }
127 
128     /**
129      * Gets the first element of this collection.
130      *
131      * @implSpec
132      * The implementation in this interface obtains an iterator of this collection, and
133      * then it obtains an element by calling the iterator's {@code next} method. Any
134      * {@code NoSuchElementException} thrown is propagated. Otherwise, it returns
135      * the element.
136      *
137      * @return the retrieved element
138      * @throws NoSuchElementException if this collection is empty
139      */
getFirst()140     default E getFirst() {
141         return this.iterator().next();
142     }
143 
144     /**
145      * Gets the last element of this collection.
146      *
147      * @implSpec
148      * The implementation in this interface obtains an iterator of the reversed view
149      * of this collection, and then it obtains an element by calling the iterator's
150      * {@code next} method. Any {@code NoSuchElementException} thrown is propagated.
151      * Otherwise, it returns the element.
152      *
153      * @return the retrieved element
154      * @throws NoSuchElementException if this collection is empty
155      */
getLast()156     default E getLast() {
157         return this.reversed().iterator().next();
158     }
159 
160     /**
161      * Removes and returns the first element of this collection (optional operation).
162      *
163      * @implSpec
164      * The implementation in this interface obtains an iterator of this collection, and then
165      * it obtains an element by calling the iterator's {@code next} method. Any
166      * {@code NoSuchElementException} thrown is propagated. It then calls the iterator's
167      * {@code remove} method. Any {@code UnsupportedOperationException} thrown is propagated.
168      * Then, it returns the element.
169      *
170      * @return the removed element
171      * @throws NoSuchElementException if this collection is empty
172      * @throws UnsupportedOperationException if this collection implementation
173      *         does not support this operation
174      */
removeFirst()175     default E removeFirst() {
176         var it = this.iterator();
177         E e = it.next();
178         it.remove();
179         return e;
180     }
181 
182     /**
183      * Removes and returns the last element of this collection (optional operation).
184      *
185      * @implSpec
186      * The implementation in this interface obtains an iterator of the reversed view of this
187      * collection, and then it obtains an element by calling the iterator's {@code next} method.
188      * Any {@code NoSuchElementException} thrown is propagated. It then calls the iterator's
189      * {@code remove} method. Any {@code UnsupportedOperationException} thrown is propagated.
190      * Then, it returns the element.
191      *
192      * @return the removed element
193      * @throws NoSuchElementException if this collection is empty
194      * @throws UnsupportedOperationException if this collection implementation
195      *         does not support this operation
196      */
removeLast()197     default E removeLast() {
198         var it = this.reversed().iterator();
199         E e = it.next();
200         it.remove();
201         return e;
202     }
203 }
204