001/*
002 * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.  Oracle designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Oracle in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
022 * or visit www.oracle.com if you need additional information or have any
023 * questions.
024 */
025
026package Torello.Java.ReadOnly;
027
028import Torello.Java.Additional.RemoveUnsupportedIterator;
029
030import java.util.function.UnaryOperator;
031
032import java.util.Spliterators;
033import java.util.Spliterator;
034import java.util.Collection;
035import java.util.RandomAccess;
036
037
038/**
039 * Immutable variant of Java Collections Framework interface
040 * <CODE>java&#46;util&#46;List&lt;E&gt;</CODE>.
041 * 
042 * <EMBED CLASS='external-html' DATA-JDK=ReadOnlyList DATA-FILE-ID=INTERFACES>
043 * 
044 * @param <E> the type of elements in this list
045 */
046@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="JDHBI_INTERFACE")
047public interface ReadOnlyList<E> extends ReadOnlyCollection<E>
048{
049    // ********************************************************************************************
050    // ********************************************************************************************
051    // Query Operations
052    // ********************************************************************************************
053    // ********************************************************************************************
054
055
056    /**
057     * Returns the number of elements in this list.  If this list contains more than
058     * {@code Integer.MAX_VALUE} elements, returns {@code Integer.MAX_VALUE}.
059     *
060     * @return the number of elements in this list
061     */
062    int size();
063
064    /**
065     * Returns {@code TRUE} if this list contains no elements.
066     * @return {@code TRUE} if this list contains no elements
067     */
068    boolean isEmpty();
069
070    /**
071     * Returns {@code TRUE} if this list contains the specified element.  More formally, returns
072     * {@code TRUE} if and only if this list contains at least one element {@code e} such that
073     * {@code Objects.equals(o, e)}.
074     *
075     * @param o element whose presence in this list is to be tested
076     * 
077     * @return {@code TRUE} if this list contains the specified element
078     * 
079     * @throws ClassCastException if the type of the specified element is incompatible with this
080     * list (<a href="Collection.html#optional-restrictions">optional</a>)
081     * 
082     * @throws NullPointerException if the specified element is null and this list does not permit
083     * null elements (<a href="Collection.html#optional-restrictions">optional</a>)
084     */
085    boolean contains(Object o);
086
087    /**
088     * Returns an iterator over the elements in this list in proper sequence.
089     * @return an iterator over the elements in this list in proper sequence
090     */
091    RemoveUnsupportedIterator<E> iterator();
092
093    /**
094     * Returns an array containing all of the elements in this list in proper sequence (from first
095     * to last element).
096     *
097     * <BR /><BR />The returned array will be "safe" in that no references to it are maintained by
098     * this list.  (In other words, this method must allocate a new array even if this list is
099     * backed by an array).  The caller is thus free to modify the returned array.
100     *
101     * <BR /><BR />This method acts as bridge between array-based and collection-based APIs.
102     *
103     * @return an array containing all of the elements in this list in proper sequence
104     */
105    Object[] toArray();
106
107    /**
108     * Returns an array containing all of the elements in this list in proper sequence (from first
109     * to last element); the runtime type of the returned array is that of the specified array.  If
110     * the list fits in the specified array, it is returned therein.  Otherwise, a new array is
111     * allocated with the runtime type of the specified array and the size of this list.
112     *
113     * <BR /><BR />If the list fits in the specified array with room to spare (i.e., the array has
114     * more elements than the list), the element in the array immediately following the end of the
115     * list is set to {@code null}.  (This is useful in determining the length of the list
116     * <i>only</i> if the caller knows that the list does not contain any null elements.)
117     *
118     * <BR /><BR />Like the {@link #toArray()} method, this method acts as bridge between
119     * array-based and collection-based APIs.  Further, this method allows precise control over the
120     * runtime type of the output array, and may, under certain circumstances, be used to save
121     * allocation costs.
122     *
123     * <BR /><BR />Suppose {@code x} is a list known to contain only strings.  The following code
124     * can be used to dump the list into a newly allocated array of {@code String}:
125     *
126     * <BR /><DIV CLASS=SNIP>{@code
127     * String[] y = x.toArray(new String[0]);
128     * }</DIV>
129     *
130     * <BR /><BR />Note that {@code toArray(new Object[0])} is identical in function to
131     * {@code toArray()}.
132     *
133     * @param a the array into which the elements of this list are to be stored, if it is big
134     * enough; otherwise, a new array of the same runtime type is allocated for this purpose.
135     * 
136     * @return an array containing the elements of this list
137     * 
138     * @throws ArrayStoreException if the runtime type of the specified array is not a supertype of
139     * the runtime type of every element in this list
140     * 
141     * @throws NullPointerException if the specified array is null
142     */
143    <T> T[] toArray(T[] a);
144
145    /**
146     * Returns {@code TRUE} if this list contains all of the elements of the specified collection.
147     * @param  c collection to be checked for containment in this list
148     * @return {@code TRUE} if this list contains all of the elements of the specified collection
149     * 
150     * @throws ClassCastException if the types of one or more elements in the specified collection
151     * are incompatible with this list
152     * (<a href="Collection.html#optional-restrictions">optional</a>)
153     * 
154     * @throws NullPointerException if the specified collection contains one or more null elements
155     * and this list does not permit null elements
156     * (<a href="Collection.html#optional-restrictions">optional</a>), or if the specified
157     * collection is null
158     * 
159     * @see #contains(Object)
160     */
161    boolean containsAll(Collection<?> c);
162
163
164    // ********************************************************************************************
165    // ********************************************************************************************
166    // Comparison and Hashing
167    // ********************************************************************************************
168    // ********************************************************************************************
169
170
171    /**
172     * Compares the specified object with this list for equality.  Returns {@code TRUE} if and only
173     * if the specified object is also a list, both lists have the same size, and all corresponding
174     * pairs of elements in the two lists are <i>equal</i>.  (Two elements {@code e1} and
175     * {@code e2} are <i>equal</i> if {@code Objects.equals(e1, e2)}.)  In other words, two lists
176     * are defined to be equal if they contain the same elements in the same order.  This
177     * definition ensures that the equals method works properly across different implementations of
178     * the {@code ReadOnlyList} interface.
179     *
180     * @param o the object to be compared for equality with this list
181     * @return {@code TRUE} if the specified object is equal to this list
182     */
183    boolean equals(Object o);
184
185    /**
186     * Returns the hash code value for this list.  The hash code of a list is defined to be the
187     * result of the following calculation:
188     * 
189     * <BR /><DIV CLASS=SNIP>{@code
190     * int hashCode = 1;
191     * for (E e : list) hashCode = 31*hashCode + (e==null ? 0 : e.hashCode());
192     * }</DIV>
193     * 
194     * <BR /><BR />This ensures that {@code list1.equals(list2)} implies that
195     * {@code list1.hashCode()==list2.hashCode()} for any two lists, {@code list1} and
196     * {@code list2}, as required by the general contract of {@code Object.hashCode}.
197     *
198     * @return the hash code value for this list
199     * 
200     * @see Object#equals(Object)
201     * @see #equals(Object)
202     */
203    int hashCode();
204
205
206    // ********************************************************************************************
207    // ********************************************************************************************
208    // Positional Access Operations
209    // ********************************************************************************************
210    // ********************************************************************************************
211
212
213    /**
214     * Returns the element at the specified position in this list.
215     * @param index index of the element to return
216     * @return the element at the specified position in this list
217     * 
218     * @throws IndexOutOfBoundsException if the index is out of range
219     * ({@code index < 0 || index >= size()})
220     */
221    E get(int index);
222
223
224    // ********************************************************************************************
225    // ********************************************************************************************
226    // Search Operations
227    // ********************************************************************************************
228    // ********************************************************************************************
229
230
231    /**
232     * Returns the index of the first occurrence of the specified element in this list, or -1 if
233     * this list does not contain the element.  More formally, returns the lowest index {@code i}
234     * such that {@code Objects.equals(o, get(i))}, or -1 if there is no such index.
235     *
236     * @param o element to search for
237     * 
238     * @return the index of the first occurrence of the specified element in this list, or -1 if
239     * this list does not contain the element
240     * 
241     * @throws ClassCastException if the type of the specified element is incompatible with this
242     * list (<a href="Collection.html#optional-restrictions">optional</a>)
243     * 
244     * @throws NullPointerException if the specified element is null and this list does not permit
245     * null elements (<a href="Collection.html#optional-restrictions">optional</a>)
246     */
247    int indexOf(Object o);
248
249    /**
250     * Returns the index of the last occurrence of the specified element in this list, or -1 if
251     * this list does not contain the element.  More formally, returns the highest index {@code i}
252     * such that {@code Objects.equals(o, get(i))}, or -1 if there is no such index.
253     *
254     * @param o element to search for
255     * 
256     * @return the index of the last occurrence of the specified element in this list, or -1 if
257     * this list does not contain the element
258     * 
259     * @throws ClassCastException if the type of the specified element is incompatible with this
260     * list (<a href="Collection.html#optional-restrictions">optional</a>)
261     * 
262     * @throws NullPointerException if the specified element is null and this list does not permit
263     * null elements (<a href="Collection.html#optional-restrictions">optional</a>)
264     */
265    int lastIndexOf(Object o);
266
267
268    // ********************************************************************************************
269    // ********************************************************************************************
270    // List Iterators
271    // ********************************************************************************************
272    // ********************************************************************************************
273
274
275    /**
276     * Returns a list iterator over the elements in this list (in proper sequence).
277     * @return a list iterator over the elements in this list (in proper sequence)
278     */
279    ReadOnlyListIterator<E> listIterator();
280
281    /**
282     * Returns a list iterator over the elements in this list (in proper sequence), starting at the
283     * specified position in the list.  The specified index indicates the first element that would
284     * be returned by an initial call to {@link ReadOnlyListIterator#next}.  An initial call to
285     * {@link ReadOnlyListIterator#previous} would return the element with the specified index
286     * minus one.
287     *
288     * @param index index of the first element to be returned from the list iterator (by a call to
289     * {@link ReadOnlyListIterator#next next})
290     * 
291     * @return a list iterator over the elements in this list (in proper sequence), starting at the
292     * specified position in the list
293     * 
294     * @throws IndexOutOfBoundsException if the index is out of range
295     * ({@code index < 0 || index > size()})
296     */
297    ReadOnlyListIterator<E> listIterator(int index);
298
299
300    // ********************************************************************************************
301    // ********************************************************************************************
302    // View
303    // ********************************************************************************************
304    // ********************************************************************************************
305
306
307    /**
308     * Returns a view of the portion of this list between the specified {@code fromIndex},
309     * inclusive, and {@code toIndex}, exclusive.  (If {@code fromIndex} and {@code toIndex} are
310     * equal, the returned list is empty.)  The returned list is backed by this list, so
311     * non-structural changes in the returned list are reflected in this list, and vice-versa.  The
312     * returned list supports all of the optional list operations supported by this list.
313     * 
314     * <BR /><BR />This method eliminates the need for explicit range operations (of the sort that
315     * commonly exist for arrays).  Any operation that expects a list can be used as a range
316     * operation by passing a subList view instead of a whole list.  For example, the following
317     * idiom removes a range of elements from a list:
318     * 
319     * <BR /><DIV CLASS=SNIP>{@code
320     * list.subList(from, to).clear();
321     * }</DIV>
322     * 
323     * <BR /><BR />Similar idioms may be constructed for {@code indexOf} and {@code lastIndexOf},
324     * and all of the algorithms in the {@code Collections} class can be applied to a subList.
325     * 
326     * <BR /><BR />The semantics of the list returned by this method become undefined if the
327     * backing list (i.e., this list) is <i>structurally modified</i> in any way other than via the
328     * returned list.  (Structural modifications are those that change the size of this list, or
329     * otherwise perturb it in such a fashion that iterations in progress may yield incorrect
330     * results.)
331     *
332     * @param fromIndex low endpoint (inclusive) of the subList
333     * 
334     * @param toIndex high endpoint (exclusive) of the subList
335     * 
336     * @return a view of the specified range within this list
337     * 
338     * @throws IndexOutOfBoundsException for an illegal endpoint index value
339     * ({@code fromIndex < 0 || toIndex > size || fromIndex > toIndex})
340     */
341    ReadOnlyList<E> subList(int fromIndex, int toIndex);
342
343    /*
344     * Creates a {@link Spliterator} over the elements in this list.
345     *
346     * <BR /><BR />The {@code Spliterator} reports {@code Spliterator.SIZED} and
347     * {@code Spliterator.ORDERED}.  Implementations should document the
348     * reporting of additional characteristic values.
349     * 
350     * <BR /><BR />The default implementation creates a
351     * <em><a href="Spliterator.html#binding">late-binding</a></em>
352     * spliterator as follows:
353     * 
354     * <UL CLASS=JDUL>
355     * 
356     * <LI> If the list is an instance of {@code RandomAccess} then the default implementation
357     *      creates a spliterator that traverses elements by invoking the method
358     *      {@link ReadOnlyList#get}.
359     *      </LI>
360     * 
361     * <LI> Otherwise, the default implementation creates a spliterator from the list's
362     *      {@code Iterator}.
363     *      </LI>
364     * 
365     * </UL>
366     *
367     * <BR /><BR />The created {@code Spliterator} additionally reports
368     * {@code Spliterator.SUBSIZED}.
369     *
370     * @return a {@code Spliterator} over the elements in this list
371     */
372    @Override
373    default Spliterator<E> spliterator()
374    {
375        return (this instanceof RandomAccess)
376            ? new AbstractReadOnlyList.RandomAccessSpliterator<>(this)
377            : Spliterators.spliterator(this.iterator(), this.size(), Spliterator.ORDERED);
378    }
379
380
381    // ********************************************************************************************
382    // ********************************************************************************************
383    // Static Builder Methods
384    // ********************************************************************************************
385    // ********************************************************************************************
386
387
388    /**
389     * Returns an unmodifiable list containing zero elements.
390     * @param <E> the {@code List}'s element type
391     * @return an empty {@code List}
392     */
393    static <E> ReadOnlyList<E> of()
394    { return InterfaceBuilder.toReadOnlyList(java.util.List.of()); }
395
396    /**
397     * Returns an unmodifiable list containing one element.
398     * @param <E> the {@code List}'s element type
399     * @param e1 the single element
400     * @return a {@code List} containing the specified element
401     * @throws NullPointerException if the element is {@code null}
402     */
403    static <E> ReadOnlyList<E> of(E e1)
404    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1)); }
405
406    /**
407     * Returns an unmodifiable list containing two elements.
408     * @param <E> the {@code List}'s element type
409     * @param e1 the first element
410     * @param e2 the second element
411     * @return a {@code List} containing the specified elements
412     * @throws NullPointerException if an element is {@code null}
413     */
414    static <E> ReadOnlyList<E> of(E e1, E e2)
415    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2)); }
416
417    /**
418     * Returns an unmodifiable list containing three elements.
419     * @param <E> the {@code List}'s element type
420     * 
421     * @param e1 the first element
422     * @param e2 the second element
423     * @param e3 the third element
424     * 
425     * @return a {@code List} containing the specified elements
426     * @throws NullPointerException if an element is {@code null}
427     */
428    static <E> ReadOnlyList<E> of(E e1, E e2, E e3)
429    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2, e3)); }
430
431    /**
432     * Returns an unmodifiable list containing four elements.
433     * @param <E> the {@code List}'s element type
434     * 
435     * @param e1 the first element
436     * @param e2 the second element
437     * @param e3 the third element
438     * @param e4 the fourth element
439     * 
440     * @return a {@code List} containing the specified elements
441     * @throws NullPointerException if an element is {@code null}
442     */
443    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4)
444    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2, e3, e4)); }
445
446    /**
447     * Returns an unmodifiable list containing five elements.
448     * @param <E> the {@code List}'s element type
449     * 
450     * @param e1 the first element
451     * @param e2 the second element
452     * @param e3 the third element
453     * @param e4 the fourth element
454     * @param e5 the fifth element
455     * 
456     * @return a {@code List} containing the specified elements
457     * @throws NullPointerException if an element is {@code null}
458     */
459    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4, E e5)
460    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2, e3, e4, e5)); }
461
462    /**
463     * Returns an unmodifiable list containing six elements.
464     * @param <E> the {@code List}'s element type
465     * 
466     * @param e1 the first element
467     * @param e2 the second element
468     * @param e3 the third element
469     * @param e4 the fourth element
470     * @param e5 the fifth element
471     * @param e6 the sixth element
472     * 
473     * @return a {@code List} containing the specified elements
474     * @throws NullPointerException if an element is {@code null}
475     */
476    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
477    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2, e3, e4, e5, e6)); }
478
479    /**
480     * Returns an unmodifiable list containing seven elements.
481     * @param <E> the {@code List}'s element type
482     * 
483     * @param e1 the first element
484     * @param e2 the second element
485     * @param e3 the third element
486     * @param e4 the fourth element
487     * @param e5 the fifth element
488     * @param e6 the sixth element
489     * @param e7 the seventh element
490     * 
491     * @return a {@code List} containing the specified elements
492     * @throws NullPointerException if an element is {@code null}
493     */
494    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
495    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2, e3, e4, e5, e6, e7)); }
496
497    /**
498     * Returns an unmodifiable list containing eight elements.
499     * @param <E> the {@code List}'s element type
500     * 
501     * @param e1 the first element
502     * @param e2 the second element
503     * @param e3 the third element
504     * @param e4 the fourth element
505     * @param e5 the fifth element
506     * @param e6 the sixth element
507     * @param e7 the seventh element
508     * @param e8 the eighth element
509     * 
510     * @return a {@code List} containing the specified elements
511     * @throws NullPointerException if an element is {@code null}
512     */
513    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
514    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(e1, e2, e3, e4, e5, e6, e7, e8)); }
515
516    /**
517     * Returns an unmodifiable list containing nine elements.
518     * @param <E> the {@code List}'s element type
519     * 
520     * @param e1 the first element
521     * @param e2 the second element
522     * @param e3 the third element
523     * @param e4 the fourth element
524     * @param e5 the fifth element
525     * @param e6 the sixth element
526     * @param e7 the seventh element
527     * @param e8 the eighth element
528     * @param e9 the ninth element
529     * 
530     * @return a {@code List} containing the specified elements
531     * @throws NullPointerException if an element is {@code null}
532     */
533    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
534    {
535        return InterfaceBuilder.toReadOnlyList
536            (java.util.List.of(e1, e2, e3, e4, e5, e6, e7, e8, e9));
537    }
538
539    /**
540     * Returns an unmodifiable list containing ten elements.
541     * @param <E> the {@code List}'s element type
542     * 
543     * @param e1 the first element
544     * @param e2 the second element
545     * @param e3 the third element
546     * @param e4 the fourth element
547     * @param e5 the fifth element
548     * @param e6 the sixth element
549     * @param e7 the seventh element
550     * @param e8 the eighth element
551     * @param e9 the ninth element
552     * @param e10 the tenth element
553     * 
554     * @return a {@code List} containing the specified elements
555     * @throws NullPointerException if an element is {@code null}
556     */
557    static <E> ReadOnlyList<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
558    {
559        return InterfaceBuilder.toReadOnlyList
560            (java.util.List.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10));
561    }
562
563    /**
564     * Returns an unmodifiable list containing an arbitrary number of elements.
565     * 
566     * @apiNote
567     * This method also accepts a single array as an argument. The element type of the resulting
568     * list will be the component type of the array, and the size of the list will be equal to the
569     * length of the array. To create a list with a single element that is an array, do the
570     * following:
571     * 
572     * <BR /><DIV CLASS=SNIP>{@code
573     * String[] array = ... ;
574     * ReadOnlyList<String[]> list = ReadOnlyList.<String[]>of(array);
575     * }</DIV>
576     * 
577     * <BR /><BR />This will cause the {@link ReadOnlyList#of(Object) ReadOnlyList.of(E)} method to
578     * be invoked instead.
579     * 
580     * @param <E> the {@code List}'s element type
581     * @param elements the elements to be contained in the list
582     * @return a {@code List} containing the specified elements
583     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
584     */
585    @SafeVarargs
586    @SuppressWarnings("varargs")
587    static <E> ReadOnlyList<E> of(E... elements)
588    { return InterfaceBuilder.toReadOnlyList(java.util.List.of(elements)); }
589
590    /**
591     * Returns a {@code ReadOnlyList} containing the elements of the given
592     * {@code ReadOnlyCollection}, in its iteration order. The given {@code Collection} must not be
593     * null, and it must not contain any null elements. If the given {@code Collection} is
594     * subsequently modified, the returned {@code ReadOnlyList} will not reflect such modifications
595     *
596     * @param <E> the {@code ReadOnlyList}'s element type
597     * @param coll a {@code ReadOnlyCollection} from which elements are drawn, must be non-null
598     * @return a {@code ReadOnlyList} containing the elements of the given {@code Collection}
599     * @throws NullPointerException if coll is null, or if it contains any nulls
600     */
601    @SuppressWarnings("unchecked")
602    static <E> ReadOnlyList<E> copyOf(ReadOnlyCollection<? extends E> coll)
603    {
604        return (ReadOnlyList.class.isAssignableFrom(coll.getClass()))
605            ? (ReadOnlyList<E>) coll
606            : new ReadOnlyArrayList<E>((ReadOnlyCollection<E>) coll, coll.size());
607    }
608}