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    // Comparison and hashing
177    // ********************************************************************************************
178    // ********************************************************************************************
179
180
181    /**
182     * Compares the specified object with this set for equality.  Returns {@code TRUE} if the
183     * specified object is also a set, the two sets have the same size, and every member of the
184     * specified set is contained in this set (or equivalently, every member of this set is
185     * contained in the specified set).  This definition ensures that the equals method works
186     * properly across different implementations of the set interface.
187     *
188     * @param o object to be compared for equality with this set
189     * @return {@code TRUE} if the specified object is equal to this set
190     */
191    boolean equals(Object o);
192
193    /**
194     * Returns the hash code value for this set.  The hash code of a set is defined to be the sum
195     * of the hash codes of the elements in the set, where the hash code of a {@code null} element
196     * is defined to be zero.  This ensures that {@code s1.equals(s2)} implies that
197     * {@code s1.hashCode()==s2.hashCode()} for any two sets {@code s1} and
198     * {@code s2}, as required by the general contract of {@code Object.hashCode}.
199     *
200     * @return the hash code value for this set
201     * @see Object#equals(Object)
202     * @see Set#equals(Object)
203     */
204    int hashCode();
205
206    /**
207     * Creates a {@code Spliterator} over the elements in this set.
208     *
209     * <BR /><BR />The {@code Spliterator} reports {@code Spliterator.DISTINCT}.  Implementations should
210     * document the reporting of additional characteristic values.
211     *
212     * @implSpec
213     * The default implementation creates a
214     * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator from the set's
215     * {@code Iterator}.
216     * 
217     * <BR /><BR />The created {@code Spliterator} additionally reports {@code Spliterator.SIZED}.
218     *
219     * @implNote
220     * The created {@code Spliterator} additionally reports {@code Spliterator.SUBSIZED}.
221     *
222     * @return a {@code Spliterator} over the elements in this set
223     */
224    @Override
225    default Spliterator<E> spliterator()
226    { return Spliterators.spliterator(this.iterator(), this.size(), Spliterator.DISTINCT); }
227
228    /**
229     * Returns an unmodifiable set containing zero elements.
230     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
231     *
232     * @param <E> the {@code Set}'s element type
233     * @return an empty {@code Set}
234     */
235    @SuppressWarnings("unchecked")
236    static <E> ReadOnlySet<E> of()
237    { return InterfaceBuilder.toReadOnlySet(Set.of()); }
238
239    /**
240     * Returns an unmodifiable set containing one element.
241     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
242     *
243     * @param <E> the {@code Set}'s element type
244     * @param e1 the single element
245     * 
246     * @return a {@code Set} containing the specified element
247     * @throws NullPointerException if the element is {@code null}
248     */
249    static <E> ReadOnlySet<E> of(E e1)
250    { return InterfaceBuilder.toReadOnlySet(Set.of(e1)); }
251
252    /**
253     * Returns an unmodifiable set containing two elements.
254     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
255     *
256     * @param <E> the {@code Set}'s element type
257     * @param e1 the first element
258     * @param e2 the second element
259     * 
260     * @return a {@code Set} containing the specified elements
261     * @throws IllegalArgumentException if the elements are duplicates
262     * @throws NullPointerException if an element is {@code null}
263     */
264    static <E> ReadOnlySet<E> of(E e1, E e2)
265    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2)); }
266
267    /**
268     * Returns an unmodifiable set containing three elements.
269     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
270     *
271     * @param <E> the {@code Set}'s element type
272     * @param e1 the first element
273     * @param e2 the second element
274     * @param e3 the third element
275     * 
276     * @return a {@code Set} containing the specified elements
277     * @throws IllegalArgumentException if there are any duplicate elements
278     * @throws NullPointerException if an element is {@code null}
279     */
280    static <E> ReadOnlySet<E> of(E e1, E e2, E e3)
281    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3)); }
282
283    /**
284     * Returns an unmodifiable set containing four elements.
285     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
286     *
287     * @param <E> the {@code Set}'s element type
288     * @param e1 the first element
289     * @param e2 the second element
290     * @param e3 the third element
291     * @param e4 the fourth element
292     * 
293     * @return a {@code Set} containing the specified elements
294     * @throws IllegalArgumentException if there are any duplicate elements
295     * @throws NullPointerException if an element is {@code null}
296     */
297    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4)
298    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4)); }
299
300    /**
301     * Returns an unmodifiable set containing five 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     * @param e3 the third element
308     * @param e4 the fourth element
309     * @param e5 the fifth element
310     * 
311     * @return a {@code Set} containing the specified elements
312     * @throws IllegalArgumentException if there are any duplicate elements
313     * @throws NullPointerException if an element is {@code null}
314     */
315    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5)
316    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4, e5)); }
317
318    /**
319     * Returns an unmodifiable set containing six elements.
320     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
321     *
322     * @param <E> the {@code Set}'s element type
323     * @param e1 the first element
324     * @param e2 the second element
325     * @param e3 the third element
326     * @param e4 the fourth element
327     * @param e5 the fifth element
328     * @param e6 the sixth element
329     * 
330     * @return a {@code Set} containing the specified elements
331     * @throws IllegalArgumentException if there are any duplicate elements
332     * @throws NullPointerException if an element is {@code null}
333     */
334    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6)
335    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4, e5, e6)); }
336
337    /**
338     * Returns an unmodifiable set containing seven elements.
339     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
340     *
341     * @param <E> the {@code Set}'s element type
342     * @param e1 the first element
343     * @param e2 the second element
344     * @param e3 the third element
345     * @param e4 the fourth element
346     * @param e5 the fifth element
347     * @param e6 the sixth element
348     * @param e7 the seventh element
349     * 
350     * @return a {@code Set} containing the specified elements
351     * @throws IllegalArgumentException if there are any duplicate elements
352     * @throws NullPointerException if an element is {@code null}
353     */
354    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)
355    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4, e5, e6, e7)); }
356
357    /**
358     * Returns an unmodifiable set containing eight elements.
359     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
360     *
361     * @param <E> the {@code Set}'s element type
362     * @param e1 the first element
363     * @param e2 the second element
364     * @param e3 the third element
365     * @param e4 the fourth element
366     * @param e5 the fifth element
367     * @param e6 the sixth element
368     * @param e7 the seventh element
369     * @param e8 the eighth element
370     * 
371     * @return a {@code Set} containing the specified elements
372     * @throws IllegalArgumentException if there are any duplicate elements
373     * @throws NullPointerException if an element is {@code null}
374     */
375    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)
376    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4, e5, e6, e7, e8)); }
377
378    /**
379     * Returns an unmodifiable set containing nine elements.
380     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
381     *
382     * @param <E> the {@code Set}'s element type
383     * @param e1 the first element
384     * @param e2 the second element
385     * @param e3 the third element
386     * @param e4 the fourth element
387     * @param e5 the fifth element
388     * @param e6 the sixth element
389     * @param e7 the seventh element
390     * @param e8 the eighth element
391     * @param e9 the ninth element
392     * 
393     * @return a {@code Set} containing the specified elements
394     * @throws IllegalArgumentException if there are any duplicate elements
395     * @throws NullPointerException if an element is {@code null}
396     */
397    static <E> ReadOnlySet<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)
398    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4, e5, e6, e7, e8, e9)); }
399
400    /**
401     * Returns an unmodifiable set containing ten elements.
402     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
403     *
404     * @param <E> the {@code Set}'s element type
405     * @param e1 the first element
406     * @param e2 the second element
407     * @param e3 the third element
408     * @param e4 the fourth element
409     * @param e5 the fifth element
410     * @param e6 the sixth element
411     * @param e7 the seventh element
412     * @param e8 the eighth element
413     * @param e9 the ninth element
414     * @param e10 the tenth element
415     * 
416     * @return a {@code Set} containing the specified elements
417     * @throws IllegalArgumentException if there are any duplicate elements
418     * @throws NullPointerException if an element is {@code null}
419     */
420    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)
421    { return InterfaceBuilder.toReadOnlySet(Set.of(e1, e2, e3, e4, e5, e6, e7, e8, e9, e10)); }
422
423    /**
424     * Returns an unmodifiable set containing an arbitrary number of elements.
425     * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
426     *
427     * @apiNote
428     * This method also accepts a single array as an argument. The element type of
429     * the resulting set will be the component type of the array, and the size of
430     * the set will be equal to the length of the array. To create a set with
431     * a single element that is an array, do the following:
432     *
433     * <pre>{@code
434     *     String[] array = ... ;
435     *     Set<String[]> list = Set.<String[]>of(array);
436     * }</pre>
437     *
438     * This will cause the {@link ReadOnlySet#of(Object) ReadOnlySet.of(E)} method
439     * to be invoked instead.
440     *
441     * @param <E> the {@code Set}'s element type
442     * @param elements the elements to be contained in the set
443     * @return a {@code Set} containing the specified elements
444     * @throws IllegalArgumentException if there are any duplicate elements
445     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
446     */
447    @SafeVarargs
448    @SuppressWarnings("varargs")
449    static <E> ReadOnlySet<E> of(E... elements)
450    { return InterfaceBuilder.toReadOnlySet(Set.of(elements)); }
451
452    /**
453     * Returns an <a href="#unmodifiable">unmodifiable Set</a> containing the elements
454     * of the given Collection. The given Collection must not be null, and it must not
455     * contain any null elements. If the given Collection contains duplicate elements,
456     * an arbitrary element of the duplicates is preserved. If the given Collection is
457     * subsequently modified, the returned Set will not reflect such modifications.
458     *
459     * @implNote
460     * If the given Collection is an <a href="#unmodifiable">unmodifiable Set</a>,
461     * calling copyOf will generally not create a copy.
462     *
463     * @param <E> the {@code Set}'s element type
464     * @param coll a {@code Collection} from which elements are drawn, must be non-null
465     * @return a {@code Set} containing the elements of the given {@code Collection}
466     * @throws NullPointerException if coll is null, or if it contains any nulls
467     */
468    @SuppressWarnings("unchecked")
469    static <E> ReadOnlySet<E> copyOf(Collection<? extends E> coll)
470    { return InterfaceBuilder.toReadOnlySet(Set.copyOf(coll)); }
471}