001/*
002 * Copyright (c) 1997, 2018, 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.Spliterators;
031import java.util.Spliterator;
032import java.util.Collection;
033
034import java.util.function.IntFunction;
035
036import java.util.stream.Stream;
037import java.util.stream.StreamSupport;
038
039/**
040 * Immutable variant of  Java Collections Framework interface
041 * <CODE>java&#46;util&#46;Collection&lt;E&gt;</CODE>.
042 * 
043 * <EMBED CLASS='external-html' DATA-JDK=ReadOnlyCollection DATA-FILE-ID=INTERFACES>
044 * 
045 * @param <E> the type of elements in this collection
046 */
047@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="JDHBI_INTERFACE")
048public interface ReadOnlyCollection<E> extends Iterable<E>
049{
050    // ********************************************************************************************
051    // ********************************************************************************************
052    // Query Operations
053    // ********************************************************************************************
054    // ********************************************************************************************
055
056
057    /**
058     * Returns the number of elements in this collection.  If this collection
059     * contains more than {@code Integer.MAX_VALUE} elements, returns
060     * {@code Integer.MAX_VALUE}.
061     *
062     * @return the number of elements in this collection
063     */
064    int size();
065
066    /**
067     * Returns {@code TRUE} if this collection contains no elements.
068     * @return {@code TRUE} if this collection contains no elements
069     */
070    boolean isEmpty();
071
072    /**
073     * Returns {@code TRUE} if this collection contains the specified element.  More formally,
074     * returns {@code TRUE} if and only if this collection contains at least one element {@code e}
075     * such that {@code Objects.equals(o, e)}.
076     *
077     * @param o element whose presence in this collection is to be tested
078     * 
079     * @return {@code TRUE} if this collection contains the specifiedelement
080     * 
081     * @throws ClassCastException if the type of the specified element is incompatible with this
082     * collection (<A HREF='#optional-restrictions'>optional-restrictions</A>)
083     * 
084     * @throws NullPointerException if the specified element is null and this collection does not
085     * permit null elements (<A HREF='#optional-restrictions'>optional-restrictions</A>)
086     */
087    boolean contains(Object o);
088
089    /**
090     * Returns an iterator over the elements in this collection.  There are no guarantees
091     * concerning the order in which the elements are returned (unless this collection is an
092     * instance of some class that provides a guarantee).
093     *
094     * @return an {@code Iterator} over the elements in this collection
095     */
096    RemoveUnsupportedIterator<E> iterator();
097
098    /**
099     * Returns an array containing all of the elements in this collection.  If this collection
100     * makes any guarantees as to what order its elements are returned by its iterator, this method
101     * must return the elements in the same order. The returned array's
102     * {@code Class.getComponentType (runtime component type)} is {@code Object}.
103     *
104     * <BR /><BR />The returned array will be "safe" in that no references to it are maintained by
105     * this collection.  (In other words, this method must allocate a new array even if this
106     * collection is backed by an array).  The caller is thus free to modify the returned array.
107     *
108     * @apiNote
109     * This method acts as a bridge between array-based and collection-based APIs.  It returns an
110     * array whose runtime type is {@code Object[]}.  Use {@link #toArray(Object[]) toArray(T[])}
111     * to reuse an existing array, or use {@link #toArray(IntFunction)} to control the runtime type
112     * of the array.
113     *
114     * @return an array, whose {@linkplain Class#getComponentType runtime component type} is
115     * {@code Object}, containing all of the elements in this collection
116     */
117    Object[] toArray();
118
119    /**
120     * Returns an array containing all of the elements in this collection; the runtime type of the
121     * returned array is that of the specified array.  If the collection fits in the specified
122     * array, it is returned therein.  Otherwise, a new array is allocated with the runtime type of
123     * the specified array and the size of this collection.
124     *
125     * <BR /><BR />If this collection fits in the specified array with room to spare (i.e., the
126     * array has more elements than this collection), the element in the array immediately
127     * following the end of the collection is set to {@code null}.  (This is useful in determining
128     * the length of this collection <i>only</i> if the caller knows that this collection does not
129     * contain any {@code null} elements.)
130     *
131     * <BR /><BR />If this collection makes any guarantees as to what order its elements are
132     * returned by its iterator, this method must return the elements in the same order.
133     *
134     * @apiNote
135     * This method acts as a bridge between array-based and collection-based APIs.  It allows an
136     * existing array to be reused under certain circumstances.  Use {@link #toArray()} to create
137     * an array whose runtime type is {@code Object[]}, or use {@link #toArray(IntFunction)} to
138     * control the runtime type of the array.
139     *
140     * <BR /><BR />Suppose {@code x} is a collection known to contain only strings.  The following
141     * code can be used to dump the collection into a previously allocated {@code String} array:
142     * 
143     * <BR /><DIV CLASS=SNIP>{@code
144     * String[] y = new String[SIZE];
145     * ...
146     * y = x.toArray(y);
147     * }</DIV>
148     *
149     * <BR /><BR />The return value is reassigned to the variable {@code y}, because a new array
150     * will be allocated and returned if the collection {@code x} has too many elements to fit into
151     * the existing array {@code y}.
152     * 
153     * <BR /><BR />Note that {@code toArray(new Object[0])} is identical in function to
154     * {@code toArray()}.
155     *
156     * @param <T> the component type of the array to contain the collection
157     * 
158     * @param a the array into which the elements of this collection are to be stored, if it is big
159     * enough; otherwise, a new array of the same runtime type is allocated for this purpose.
160     * 
161     * @return an array containing all of the elements in this collection
162     * 
163     * @throws ArrayStoreException if the runtime type of any element in this collection is not
164     * assignable to the {@linkplain Class#getComponentType runtime component type} of the
165     * specified array
166     * 
167     * @throws NullPointerException if the specified array is null
168     */
169    <T> T[] toArray(T[] a);
170
171    /**
172     * Returns an array containing all of the elements in this collection, using the provided
173     * {@code generator} function to allocate the returned array.
174     *
175     * <BR /><BR />If this collection makes any guarantees as to what order its elements are
176     * returned by its iterator, this method must return the elements in the same order.
177     * 
178     * @apiNote
179     * This method acts as a bridge between array-based and collection-based APIs.  It allows
180     * creation of an array of a particular runtime type. Use {@link #toArray()} to create an array
181     * whose runtime type is {@code Object[]}, or use {@link #toArray(Object[]) toArray(T[])} to
182     * reuse an existing array.
183     *
184     * <BR /><BR />Suppose {@code x} is a collection known to contain only strings.  The following
185     * code can be used to dump the collection into a newly allocated array of {@code String}:
186     *
187     * <BR /><DIV CLASS=SNIP>{@code
188     * String[] y = x.toArray(String[]::new);
189     * }</DIV>
190     *
191     * <BR /><BR />The default implementation calls the generator function with zero and then
192     * passes the resulting array to {@link #toArray(Object[]) toArray(T[])}.
193     *
194     * @param <T> the component type of the array to contain the collection
195     * 
196     * @param generator a function which produces a new array of the desired type and the provided
197     * length
198     * 
199     * @return an array containing all of the elements in this collection
200     * 
201     * @throws ArrayStoreException if the runtime type of any element in this collection is not
202     * assignable to the {@linkplain Class#getComponentType runtime component type} of the
203     * generated array
204     * 
205     * @throws NullPointerException if the generator function is null
206     */
207    default <T> T[] toArray(IntFunction<T[]> generator)
208    { return toArray(generator.apply(0)); }
209
210    /**
211     * Simply copies the contents of {@code 'this'} instance of {@code ReadOnlyCollection} into
212     * the user-provided {@code 'collection'} data-structure.
213     * 
214     * @param collection Any Java Collection instance.  This collection's {@code 'add(E e)'} method
215     * will be utilized for performing the coying.
216     */
217    default void copyIntoCollection(Collection<? super E> collection)
218    { for (E e : this) collection.add(e); }
219
220
221    // ********************************************************************************************
222    // ********************************************************************************************
223    // Bulk Operations
224    // ********************************************************************************************
225    // ********************************************************************************************
226
227
228    /**
229     * Returns {@code TRUE} if this collection contains all of the elements in the specified
230     * collection.
231     *
232     * @param c collection to be checked for containment in this collection
233     * 
234     * @return {@code TRUE} if this collection contains all of the elements in the specified
235     * collection
236     * 
237     * @throws ClassCastException if the types of one or more elements in the specified collection
238     * are incompatible with this collection
239     * (<A HREF='#optional-restrictions'>optional-restrictions</A>)
240     * 
241     * @throws NullPointerException if the specified collection contains one or more null elements
242     * and this collection does not permit null elements
243     * (<A HREF='#optional-restrictions'>optional-restrictions</A>),
244     * or if the specified collection is null.
245     * 
246     * @see #contains(Object)
247     */
248    boolean containsAll(Collection<?> c);
249
250
251    // ********************************************************************************************
252    // ********************************************************************************************
253    // contains - using Var-Args Arrays
254    // ********************************************************************************************
255    // ********************************************************************************************
256
257
258    /**
259     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
260     * <B STYLE='color: red;'>contains every one of the elements</B> in Var-Args Parameter
261     * {@code 'elements'}
262     * 
263     * @param elements a list of elements
264     * 
265     * @return {@code TRUE} If and only if {@code 'this'} instance contains every element in
266     * {@code 'elements'}
267     */
268    default boolean containsAND(Object... elements)
269    {
270        for (Object elem : elements) if (! this.contains(elem)) return false;
271        return true;
272    }
273
274    /**
275     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
276     * <B STYLE='color: red;'>does not contain any of the elements</B> in Var-Args Parameter
277     * {@code 'elements'}
278     * 
279     * @param elements a list of elements
280     * 
281     * @return {@code TRUE} If and only if {@code 'this'} instance contains none of the elements in
282     * {@code 'elements'}
283     */
284    default boolean containsNAND(Object... elements)
285    {
286        for (Object elem : elements) if (this.contains(elem)) return false;
287        return true;
288    }
289
290    /**
291     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
292     * <B STYLE='color: red;'>contains at least one of the elements</B> in Var-Args Parameter
293     * {@code 'elements'}
294     * 
295     * @param elements a list of elements
296     * 
297     * @return {@code TRUE} If and only if {@code 'this'} instance contains one or more of the
298     * elements in {@code 'elements'}
299     */
300    default boolean containsOR(Object... elements)
301    {
302        for (Object elem : elements) if (this.contains(elem)) return true;
303        return false;
304    }
305
306    /**
307     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
308     * <B STYLE='color: red;'>contains precisely one of the elements</B> in Var-Args Parameter
309     * {@code 'elements'}
310     * 
311     * @param elements a list of elements
312     * 
313     * @return {@code TRUE} If and only if {@code 'this'} instance has exactly one element that is
314     * also in {@code 'elements'}
315     */
316    default boolean containsXOR(Object... elements)
317    {
318        boolean found = false;
319
320        for (Object elem : elements)
321
322            if (this.contains(elem))
323            {
324                if (found) return false;
325                else found = true;
326            }
327
328        return found;
329    }
330
331
332    // ********************************************************************************************
333    // ********************************************************************************************
334    // contains - using java.lang.Iterable
335    // ********************************************************************************************
336    // ********************************************************************************************
337
338
339    /**
340     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
341     * <B STYLE='color: red;'>contains every one of the elements</B> in {@code Iterable} parameter
342     * {@code 'i'}
343     * 
344     * @param i any Java {@code Iterable}
345     * 
346     * @return {@code TRUE} If and only if {@code 'this'} instance contains every element in
347     * {@code 'i'}
348     */
349    default boolean containsAND(Iterable<?> i)
350    {
351        for (Object o: i) if (! this.contains(o)) return false;
352        return true;
353    }
354
355    /**
356     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
357     * <B STYLE='color: red;'>does not contain any of the elements</B> in {@code Iterable}
358     * parameter {@code 'i'}
359     * 
360     * @param i any Java {@code Iterable}
361     * 
362     * @return {@code TRUE} If and only if {@code 'this'} instance contains none of the elements in
363     * {@code 'i'}
364     */
365    default boolean containsNAND(Iterable<?> i)
366    {
367        for (Object o: i) if (this.contains(o)) return false;
368        return true;
369    }
370
371    /**
372     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
373     * <B STYLE='color: red;'>contains at least one of the elements</B> in {@code Iterable}
374     * parameter {@code 'i'}
375     * 
376     * @param i any Java {@code Iterable}
377     * 
378     * @return {@code TRUE} If and only if {@code 'this'} instance contains one or more of the
379     * elements in {@code 'i'}
380     */
381    default boolean containsOR(Iterable<?> i)
382    {
383        for (Object o: i) if (this.contains(o)) return true;
384        return false;
385    }
386
387    /**
388     * Checks to ensure that {@code 'this'} instance of {@code ReadOnlyCollection}
389     * <B STYLE='color: red;'>contains precisely one of the elements</B> in {@code Iterable}
390     * parameter {@code 'i'}
391     *
392     * @param i any Java {@code Iterable}
393     * 
394     * @return {@code TRUE} If and only if {@code 'this'} instance has exactly one element that is
395     * also in {@code 'i'}
396     */
397    default boolean containsXOR(Iterable<?> i)
398    {
399        boolean found = false;
400
401        for (Object o: i)
402
403            if (this.contains(o))
404            {
405                if (found) return false;
406                else found = true;
407            }
408
409        return found;
410    }
411
412
413    // ********************************************************************************************
414    // ********************************************************************************************
415    // Comparison and Hashing
416    // ********************************************************************************************
417    // ********************************************************************************************
418
419
420    /**
421     * Compares the specified object with this collection for equality.
422     * 
423     * <BR /><BR />While the {@code ReadOnlyCollection} interface adds no stipulations to the
424     * general contract for the {@code Object.equals}, programmers who implement the
425     * {@code ReadOnlyCollection} interface "directly" (in other words, create a class that is a
426     * {@code ReadOnlyCollection} but is not a {@code ReadOnlySet} or a {@code ReadOnlyList}) must
427     * exercise care if they choose to override the {@code Object.equals}.  It is not necessary to
428     * do so, and the simplest course of action is to rely on {@code Object}'s implementation, but
429     * the implementor may wish to implement a "value comparison" in place of the default
430     * "reference comparison."  (The {@code ReadOnlyList} and {@code ReadOnlySet} interfaces
431     * mandate such value comparisons.)
432     * 
433     * <BR /><BR />The general contract for the {@code Object.equals} method states that equals
434     * must be symmetric (in other words, {@code a.equals(b)} if and only if {@code b.equals(a)}).
435     * The contracts for {@code ReadOnlyList.equals} and {@code ReadOnlySet.equals} state that
436     * lists are only equal to other lists, and sets to other sets.  Thus, a custom {@code equals}
437     * method for a collection class that implements neither the {@code ReadOnlyList} nor
438     * {@code ReadOnlySet} interface must return {@code FALSE} when this collection is compared to
439     * any list or set.  (By the same logic, it is not possible to write a class that correctly
440     * implements both the {@code ReadOnlySet} and {@code ReadOnlyList} interfaces.)
441     *
442     * @param o object to be compared for equality with this collection
443     * 
444     * @return {@code TRUE} if the specified object is equal to this collection
445     *
446     * @see Object#equals(Object)
447     * @see ReadOnlySet#equals(Object)
448     * @see ReadOnlyList#equals(Object)
449     */
450    boolean equals(Object o);
451
452    /**
453     * Returns the hash code value for this collection.  While the {@code Collection} interface
454     * adds no stipulations to the general contract for the {@code Object.hashCode} method,
455     * programmers should take note that any class that overrides the {@code Object.equals} method
456     * must also override the {@code Object.hashCode} method in order to satisfy the general
457     * contract for the {@code Object.hashCode} method.  In particular, {@code c1.equals(c2)}
458     * implies that {@code c1.hashCode()==c2.hashCode()}.
459     *
460     * @return the hash code value for this collection
461     *
462     * @see Object#hashCode()
463     * @see Object#equals(Object)
464     */
465    int hashCode();
466
467    /**
468     * Creates a {@link Spliterator} over the elements in this collection.
469     * 
470     * <BR /><BR />Implementations should document characteristic values reported by the
471     * spliterator.  Such characteristic values are not required to be reported if the spliterator
472     * reports {@code Spliterator.SIZED} and this collection contains no elements.
473     * 
474     * <BR /><BR />The default implementation should be overridden by subclasses that can return a
475     * more efficient spliterator.  In order to preserve expected laziness behavior for the
476     * {@link #stream()} and {@link #parallelStream()} methods, spliterators should either have the
477     * characteristic of {@code IMMUTABLE} or {@code CONCURRENT}, or be
478     * <em><a href="Spliterator.html#binding">late-binding</a></em>.  If none of these is
479     * practical, the overriding class should describe the spliterator's documented policy of
480     * binding and structural interference, and should override the {@link #stream()} and
481     * {@link #parallelStream()} methods to create streams using a {@code Supplier} of the
482     * spliterator, as in:
483     * 
484     * <BR /><DIV CLASS=SNIP>{@code
485     * Stream<E> s = StreamSupport.stream(() -> spliterator(), spliteratorCharacteristics)
486     * }</DIV>
487     * 
488     * <BR /><BR />These requirements ensure that streams produced by the {@link #stream()} and
489     * {@link #parallelStream()} methods will reflect the contents of the collection as of
490     * initiation of the terminal stream operation.
491     *
492     * <BR /><BR />The default implementation creates a <em><a href="Spliterator.html#binding">
493     * late-binding</a></em> spliterator from the collection's {@code Iterator}.
494     * 
495     * <BR /><BR />The created {@code Spliterator} reports {@code Spliterator.SIZED}.
496     * 
497     * @implNote
498     * The created {@code Spliterator} additionally reports {@code Spliterator.SUBSIZED}.
499     * 
500     * <BR /><BR />If a spliterator covers no elements then the reporting of additional
501     * characteristic values, beyond that of {@code SIZED} and {@code SUBSIZED}, does not aid
502     * clients to control, specialize or simplify computation.  However, this does enable shared
503     * use of an immutable and empty spliterator instance (see
504     * {@code Spliterators.emptySpliterator()}) for empty collections, and enables clients to
505     * determine if such a spliterator covers no elements. 
506     * 
507     * @return a {@code Spliterator} over the elements in this collection
508     */
509    @Override
510    default Spliterator<E> spliterator()
511    { return Spliterators.spliterator(this.iterator(), this.size(), 0); }
512
513    /**
514     * Returns a sequential {@code Stream} with this collection as its source.
515     * 
516     * <BR /><BR />This method should be overridden when the {@link #spliterator()} method cannot
517     * return a spliterator that is {@code IMMUTABLE}, {@code CONCURRENT}, or
518     * <em>late-binding</em>. (See {@link #spliterator()} for details.)
519     * 
520     * <BR /><BR />The default implementation creates a sequential {@code Stream} from the
521     * collection's {@code Spliterator}.
522     * 
523     * @return a sequential {@code Stream} over the elements in this collection
524     */
525    default Stream<E> stream()
526    { return StreamSupport.stream(spliterator(), false); }
527
528    /**
529     * Returns a possibly parallel {@code Stream} with this collection as its source.  It is
530     * allowable for this method to return a sequential stream.
531     *
532     * <BR /><BR />This method should be overridden when the {@link #spliterator()} method cannot
533     * return a spliterator that is {@code IMMUTABLE}, {@code CONCURRENT}, or
534     * <em>late-binding</em>. (See {@link #spliterator()} for details.)
535     *
536     * @implSpec
537     * The default implementation creates a parallel {@code Stream} from the collection's
538     * {@code Spliterator}.
539     *
540     * @return a possibly parallel {@code Stream} over the elements in this collection
541     */
542    default Stream<E> parallelStream()
543    { return StreamSupport.stream(spliterator(), true); }
544}