001/*
002 * Copyright (c) 1997, 2023, 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 */
025package Torello.Java.ReadOnly;
026
027import Torello.Java.Additional.RemoveUnsupportedIterator;
028
029import java.util.Spliterator;
030import java.util.Spliterators;
031import java.util.Collection;
032import java.util.Set; // return Set.of(...)
033
034/**
035 * Immutable variant of Java Collections Framework interface
036 * <CODE>java&#46;util&#46;Set&lt;E&gt;</CODE>.
037 * 
038 * <EMBED CLASS='external-html' DATA-JDK=ReadOnlySet DATA-FILE-ID=INTERFACES>
039 * 
040 * @param <E> the type of elements maintained by this set
041 */
042@Torello.JavaDoc.JDHeaderBackgroundImg(EmbedTagFileID="JDHBI_INTERFACE")
043public interface ReadOnlySet<E> extends ReadOnlyCollection<E>
044{
045    // ********************************************************************************************
046    // ********************************************************************************************
047    // Query Operations
048    // ********************************************************************************************
049    // ********************************************************************************************
050
051
052    /**
053     * Returns the number of elements in this set (its cardinality).  If this set contains more
054     * than {@code Integer.MAX_VALUE} elements, returns {@code Integer.MAX_VALUE}.
055     *
056     * @return the number of elements in this set (its cardinality)
057     */
058    int size();
059
060    /**
061     * Returns {@code TRUE} if this set contains no elements.
062     * @return {@code TRUE} if this set contains no elements
063     */
064    boolean isEmpty();
065
066    /**
067     * Returns {@code TRUE} if this set contains the specified element.  More formally, returns
068     * {@code TRUE} if and only if this set contains an element {@code e} such that
069     * {@code Objects.equals(o, e)}.
070     *
071     * @param o element whose presence in this set is to be tested
072     * @return {@code TRUE} if this set contains the specified element
073     * 
074     * @throws ClassCastException if the type of the specified element is incompatible with this
075     * set (<a href="Collection.html#optional-restrictions">optional</a>)
076     * 
077     * @throws NullPointerException if the specified element is null and this set does not permit
078     * null elements (<a href="Collection.html#optional-restrictions">optional</a>)
079     */
080    boolean contains(Object o);
081
082    /**
083     * Returns an iterator over the elements in this set.  The elements are returned in no
084     * particular order (unless this set is an instance of some class that provides a guarantee).
085     *
086     * @return an iterator over the elements in this set
087     */
088    RemoveUnsupportedIterator<E> iterator();
089
090    /**
091     * Returns an array containing all of the elements in this set.  If this set makes any
092     * guarantees as to what order its elements are returned by its iterator, this method must
093     * return the elements in the same order.
094     *
095     * <BR /><BR />The returned array will be "safe" in that no references to it are maintained by this set.
096     * (In other words, this method must allocate a new array even if this set is backed by an
097     * array).  The caller is thus free to modify the returned array.
098     *
099     * <BR /><BR />This method acts as bridge between array-based and collection-based APIs.
100     *
101     * @return an array containing all the elements in this set
102     */
103    Object[] toArray();
104
105    /**
106     * Returns an array containing all of the elements in this set; the runtime type of the
107     * returned array is that of the specified array.  If the set fits in the specified array, it
108     * is returned therein.  Otherwise, a new array is allocated with the runtime type of the
109     * specified array and the size of this set.
110     *
111     * <BR /><BR />If this set fits in the specified array with room to spare (i.e., the array has more
112     * elements than this set), the element in the array immediately following the end of the set
113     * is set to {@code null}.  (This is useful in determining the length of this set <i>only</i>
114     * if the caller knows that this set does not contain any null elements.)
115     *
116     * <BR /><BR />If this set makes any guarantees as to what order its elements are returned by its
117     * iterator, this method must return the elements in the same order.
118     *
119     * <BR /><BR />Like the {@link #toArray()} method, this method acts as bridge between array-based and
120     * collection-based APIs.  Further, this method allows precise control over the runtime type of
121     * the output array, and may, under certain circumstances, be used to save allocation costs.
122     *
123     * <BR /><BR />Suppose {@code x} is a set known to contain only strings.  The following code can be used
124     * to dump the set into a newly allocated array of {@code String}:
125     *
126     * <pre>
127     *     String[] y = x.toArray(new String[0]);</pre>
128     *
129     * Note that {@code toArray(new Object[0])} is identical in function to
130     * {@code toArray()}.
131     *
132     * @param a the array into which the elements of this set are to be stored, if it is big
133     * enough; otherwise, a new array of the same runtime type is allocated for this purpose.
134     * 
135     * @return an array containing all the elements in this set
136     * 
137     * @throws ArrayStoreException if the runtime type of the specified array is not a supertype of
138     * the runtime type of every element in this set
139     * 
140     * @throws NullPointerException if the specified array is null
141     */
142    <T> T[] toArray(T[] a);
143
144
145    // ********************************************************************************************
146    // ********************************************************************************************
147    // Bulk Operations
148    // ********************************************************************************************
149    // ********************************************************************************************
150
151
152    /**
153     * Returns {@code TRUE} if this set contains all of the elements of the specified collection.
154     * If the specified collection is also a set, this method returns {@code TRUE} if it is a
155     * <i>subset</i> of this set.
156     *
157     * @param  c collection to be checked for containment in this set
158     * @return {@code TRUE} if this set contains all of the elements of the specified collection
159     * 
160     * @throws ClassCastException if the types of one or more elements in the specified collection
161     * are incompatible with this set
162     * (<a href="Collection.html#optional-restrictions">optional</a>)
163     * 
164     * @throws NullPointerException if the specified collection contains one or more null elements
165     * and this set does not permit null elements
166     * (<a href="Collection.html#optional-restrictions">optional</a>), or if the specified
167     * collection is null
168     * 
169     * @see #contains(Object)
170     */
171    boolean containsAll(Collection<?> c);
172
173
174    // ********************************************************************************************
175    // ********************************************************************************************
176    // Change The Type, Clone the Internal Data-Structure
177    // ********************************************************************************************
178    // ********************************************************************************************
179
180
181    /**
182     * Clones the internal {@code java.util.Set} representation, and returns it.  This is the
183     * Top-Level Interface-Variant of this method.  It returns the Interface-Implementation
184     * {@code java.util.Set}.
185     * 
186     * <BR /><BR /><B CLASS=JDDescLabel>Alternate Variant:</B>
187     * 
188     * <BR />The two classes which implement the interface {@code ReadOnlySet}
189     * (which are {@link ReadOnlyHashSet} and {@link ReadOnlyTreeSet}), for convenience, also 
190     * implement an identical "Wrap To" Method which returns the exact type of the internal
191     * {@code Set} representation (which are {@code java.util.HashSet} and
192     * {@code java.util.TreeSet}) - rather than the Top-Level Interface-Type {@code java.util.Set}.
193     * 
194     * @return <UL CLASS=JDUL>
195     * 
196     * <LI> For the sub-class {@link ReadOnlyHashSet}, this will return a cloned instance of the
197     *      internal {@code java.util.HashSet}.
198     *      <BR /><BR />
199     *      </LI>
200     * 
201     * <LI> For the sub-class {@link ReadOnlyTreeSet}, this will return a cloned instance of the
202     *      internal {@code java.util.TreeSet}.
203     *      </LI>
204     * 
205     * </UL>
206     */
207    Set<E> cloneToSet();
208
209    /**
210     * Invokes {@code java.util.Collections.unmodifiableSet} on the internal {@code Set}
211     * 
212     * <EMBED CLASS='external-html' DATA-JDK=Set DATA-RET_TYPE=Set
213     *      DATA-FILE-ID=WRAP_TO_IMMUTABLE>
214     * 
215     * @return A {@code Set} which adheres to the JDK interface {@code java.util.Set}, but throws
216     * an {@code UnsupportedOperationException} if a user attempts to invoke a Mutator-Method on
217     * the returned instance.
218     */
219    Set<E> wrapToImmutableSet();
220
221
222    // ********************************************************************************************
223    // ********************************************************************************************
224    // Comparison and hashing
225    // ********************************************************************************************
226    // ********************************************************************************************
227
228
229    /**
230     * Compares the specified object with this set for equality.  Returns {@code TRUE} if the
231     * specified object is also a set, the two sets have the same size, and every member of the
232     * specified set is contained in this set (or equivalently, every member of this set is
233     * contained in the specified set).  This definition ensures that the equals method works
234     * properly across different implementations of the set interface.
235     *
236     * @param o object to be compared for equality with this set
237     * @return {@code TRUE} if the specified object is equal to this set
238     */
239    boolean equals(Object o);
240
241    /**
242     * Returns the hash code value for this set.  The hash code of a set is defined to be the sum
243     * of the hash codes of the elements in the set, where the hash code of a {@code null} element
244     * is defined to be zero.  This ensures that {@code s1.equals(s2)} implies that
245     * {@code s1.hashCode()==s2.hashCode()} for any two sets {@code s1} and
246     * {@code s2}, as required by the general contract of {@code Object.hashCode}.
247     *
248     * @return the hash code value for this set
249     * @see Object#equals(Object)
250     * @see Set#equals(Object)
251     */
252    int hashCode();
253
254    /**
255     * Creates a {@code Spliterator} over the elements in this set.
256     *
257     * <BR /><BR />The {@code Spliterator} reports {@code Spliterator.DISTINCT}.  Implementations should
258     * document the reporting of additional characteristic values.
259     *
260     * @implSpec
261     * The default implementation creates a
262     * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator from the set's
263     * {@code Iterator}.
264     * 
265     * <BR /><BR />The created {@code Spliterator} additionally reports {@code Spliterator.SIZED}.
266     *
267     * @implNote
268     * The created {@code Spliterator} additionally reports {@code Spliterator.SUBSIZED}.
269     *
270     * @return a {@code Spliterator} over the elements in this set
271     */
272    @Override
273    default Spliterator<E> spliterator()
274    { return Spliterators.spliterator(this.iterator(), this.size(), Spliterator.DISTINCT); }
275
276    /**
277     * Returns an unmodifiable set containing zero elements.
278     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
279     *
280     * @param <E> the {@code Set}'s element type
281     * @return an empty {@code Set}
282     */
283    @SuppressWarnings("unchecked")
284    static <E> ReadOnlySet<E> of()
285    { return new JavaHTMLReadOnlySet<>(Set.of()); }
286
287    /**
288     * Returns an unmodifiable set containing one element.
289     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
290     *
291     * @param <E> the {@code Set}'s element type
292     * @param e1 the single element
293     * 
294     * @return a {@code Set} containing the specified element
295     * @throws NullPointerException if the element is {@code null}
296     */
297    static <E> ReadOnlySet<E> of(E e1)
298    { return new JavaHTMLReadOnlySet<>(Set.of(e1)); }
299
300    /**
301     * Returns an unmodifiable set containing two elements.
302     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
303     *
304     * @param <E> the {@code Set}'s element type
305     * @param e1 the first element
306     * @param e2 the second element
307     * 
308     * @return a {@code Set} containing the specified elements
309     * @throws IllegalArgumentException if the elements are duplicates
310     * @throws NullPointerException if an element is {@code null}
311     */
312    static <E> ReadOnlySet<E> of(E e1, E e2)
313    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2)); }
314
315    /**
316     * Returns an unmodifiable set containing three elements.
317     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
318     *
319     * @param <E> the {@code Set}'s element type
320     * @param e1 the first element
321     * @param e2 the second element
322     * @param e3 the third element
323     * 
324     * @return a {@code Set} containing the specified elements
325     * @throws IllegalArgumentException if there are any duplicate elements
326     * @throws NullPointerException if an element is {@code null}
327     */
328    static <E> ReadOnlySet<E> of(E e1, E e2, E e3)
329    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3)); }
330
331    /**
332     * Returns an unmodifiable set containing four elements.
333     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
334     *
335     * @param <E> the {@code Set}'s element type
336     * @param e1 the first element
337     * @param e2 the second element
338     * @param e3 the third element
339     * @param e4 the fourth element
340     * 
341     * @return a {@code Set} containing the specified elements
342     * @throws IllegalArgumentException if there are any duplicate elements
343     * @throws NullPointerException if an element is {@code null}
344     */
345    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4)
346    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4)); }
347
348    /**
349     * Returns an unmodifiable set containing five elements.
350     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
351     *
352     * @param <E> the {@code Set}'s element type
353     * @param e1 the first element
354     * @param e2 the second element
355     * @param e3 the third element
356     * @param e4 the fourth element
357     * @param e5 the fifth element
358     * 
359     * @return a {@code Set} containing the specified elements
360     * @throws IllegalArgumentException if there are any duplicate elements
361     * @throws NullPointerException if an element is {@code null}
362     */
363    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5)
364    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4, e5)); }
365
366    /**
367     * Returns an unmodifiable set containing six elements.
368     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
369     *
370     * @param <E> the {@code Set}'s element type
371     * @param e1 the first element
372     * @param e2 the second element
373     * @param e3 the third element
374     * @param e4 the fourth element
375     * @param e5 the fifth element
376     * @param e6 the sixth element
377     * 
378     * @return a {@code Set} containing the specified elements
379     * @throws IllegalArgumentException if there are any duplicate elements
380     * @throws NullPointerException if an element is {@code null}
381     */
382    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
383    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4, e5, e6)); }
384
385    /**
386     * Returns an unmodifiable set containing seven elements.
387     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
388     *
389     * @param <E> the {@code Set}'s element type
390     * @param e1 the first element
391     * @param e2 the second element
392     * @param e3 the third element
393     * @param e4 the fourth element
394     * @param e5 the fifth element
395     * @param e6 the sixth element
396     * @param e7 the seventh element
397     * 
398     * @return a {@code Set} containing the specified elements
399     * @throws IllegalArgumentException if there are any duplicate elements
400     * @throws NullPointerException if an element is {@code null}
401     */
402    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
403    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4, e5, e6, e7)); }
404
405    /**
406     * Returns an unmodifiable set containing eight elements.
407     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
408     *
409     * @param <E> the {@code Set}'s element type
410     * @param e1 the first element
411     * @param e2 the second element
412     * @param e3 the third element
413     * @param e4 the fourth element
414     * @param e5 the fifth element
415     * @param e6 the sixth element
416     * @param e7 the seventh element
417     * @param e8 the eighth element
418     * 
419     * @return a {@code Set} containing the specified elements
420     * @throws IllegalArgumentException if there are any duplicate elements
421     * @throws NullPointerException if an element is {@code null}
422     */
423    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
424    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4, e5, e6, e7, e8)); }
425
426    /**
427     * Returns an unmodifiable set containing nine elements.
428     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
429     *
430     * @param <E> the {@code Set}'s element type
431     * @param e1 the first element
432     * @param e2 the second element
433     * @param e3 the third element
434     * @param e4 the fourth element
435     * @param e5 the fifth element
436     * @param e6 the sixth element
437     * @param e7 the seventh element
438     * @param e8 the eighth element
439     * @param e9 the ninth element
440     * 
441     * @return a {@code Set} containing the specified elements
442     * @throws IllegalArgumentException if there are any duplicate elements
443     * @throws NullPointerException if an element is {@code null}
444     */
445    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
446    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4, e5, e6, e7, e8, e9)); }
447
448    /**
449     * Returns an unmodifiable set containing ten elements.
450     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
451     *
452     * @param <E> the {@code Set}'s element type
453     * @param e1 the first element
454     * @param e2 the second element
455     * @param e3 the third element
456     * @param e4 the fourth element
457     * @param e5 the fifth element
458     * @param e6 the sixth element
459     * @param e7 the seventh element
460     * @param e8 the eighth element
461     * @param e9 the ninth element
462     * @param e10 the tenth element
463     * 
464     * @return a {@code Set} containing the specified elements
465     * @throws IllegalArgumentException if there are any duplicate elements
466     * @throws NullPointerException if an element is {@code null}
467     */
468    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)
469    { return new JavaHTMLReadOnlySet<>(Set.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)); }
470
471    /**
472     * Returns an unmodifiable set containing an arbitrary number of elements.
473     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
474     *
475     * @apiNote
476     * This method also accepts a single array as an argument. The element type of
477     * the resulting set will be the component type of the array, and the size of
478     * the set will be equal to the length of the array. To create a set with
479     * a single element that is an array, do the following:
480     *
481     * <pre>{@code
482     *     String[] array = ... ;
483     *     Set<String[]> list = Set.<String[]>of(array);
484     * }</pre>
485     *
486     * This will cause the {@link ReadOnlySet#of(Object) ReadOnlySet.of(E)} method
487     * to be invoked instead.
488     *
489     * @param <E> the {@code Set}'s element type
490     * @param elements the elements to be contained in the set
491     * @return a {@code Set} containing the specified elements
492     * @throws IllegalArgumentException if there are any duplicate elements
493     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
494     */
495    @SafeVarargs
496    @SuppressWarnings("varargs")
497    static <E> ReadOnlySet<E> of(E... elements)
498    { return new JavaHTMLReadOnlySet<>(Set.of(elements)); }
499
500    /**
501     * Returns an <a href="#unmodifiable">unmodifiable Set</a> containing the elements
502     * of the given Collection. The given Collection must not be null, and it must not
503     * contain any null elements. If the given Collection contains duplicate elements,
504     * an arbitrary element of the duplicates is preserved. If the given Collection is
505     * subsequently modified, the returned Set will not reflect such modifications.
506     *
507     * @implNote
508     * If the given Collection is an <a href="#unmodifiable">unmodifiable Set</a>,
509     * calling copyOf will generally not create a copy.
510     *
511     * @param <E> the {@code Set}'s element type
512     * @param coll a {@code Collection} from which elements are drawn, must be non-null
513     * @return a {@code Set} containing the elements of the given {@code Collection}
514     * @throws NullPointerException if coll is null, or if it contains any nulls
515     */
516    @SuppressWarnings("unchecked")
517    static <E> ReadOnlySet<E> copyOf(Collection<? extends E> coll)
518    { return new JavaHTMLReadOnlySet<>(Set.copyOf(coll)); }
519}