1 /*
2  * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package java.util;
27 
28 /**
29  * A collection that contains no duplicate elements.  More formally, sets
30  * contain no pair of elements {@code e1} and {@code e2} such that
31  * {@code e1.equals(e2)}, and at most one null element.  As implied by
32  * its name, this interface models the mathematical <i>set</i> abstraction.
33  *
34  * <p>The {@code Set} interface places additional stipulations, beyond those
35  * inherited from the {@code Collection} interface, on the contracts of all
36  * constructors and on the contracts of the {@code add}, {@code equals} and
37  * {@code hashCode} methods.  Declarations for other inherited methods are
38  * also included here for convenience.  (The specifications accompanying these
39  * declarations have been tailored to the {@code Set} interface, but they do
40  * not contain any additional stipulations.)
41  *
42  * <p>The additional stipulation on constructors is, not surprisingly,
43  * that all constructors must create a set that contains no duplicate elements
44  * (as defined above).
45  *
46  * <p>Note: Great care must be exercised if mutable objects are used as set
47  * elements.  The behavior of a set is not specified if the value of an object
48  * is changed in a manner that affects {@code equals} comparisons while the
49  * object is an element in the set.  A special case of this prohibition is
50  * that it is not permissible for a set to contain itself as an element.
51  *
52  * <p>Some set implementations have restrictions on the elements that
53  * they may contain.  For example, some implementations prohibit null elements,
54  * and some have restrictions on the types of their elements.  Attempting to
55  * add an ineligible element throws an unchecked exception, typically
56  * {@code NullPointerException} or {@code ClassCastException}.  Attempting
57  * to query the presence of an ineligible element may throw an exception,
58  * or it may simply return false; some implementations will exhibit the former
59  * behavior and some will exhibit the latter.  More generally, attempting an
60  * operation on an ineligible element whose completion would not result in
61  * the insertion of an ineligible element into the set may throw an
62  * exception or it may succeed, at the option of the implementation.
63  * Such exceptions are marked as "optional" in the specification for this
64  * interface.
65  *
66  * <h2><a id="unmodifiable">Unmodifiable Sets</a></h2>
67  * <p>The {@link Set#of(Object...) Set.of} and
68  * {@link Set#copyOf Set.copyOf} static factory methods
69  * provide a convenient way to create unmodifiable sets. The {@code Set}
70  * instances created by these methods have the following characteristics:
71  *
72  * <ul>
73  * <li>They are <a href="Collection.html#unmodifiable"><i>unmodifiable</i></a>. Elements cannot
74  * be added or removed. Calling any mutator method on the Set
75  * will always cause {@code UnsupportedOperationException} to be thrown.
76  * However, if the contained elements are themselves mutable, this may cause the
77  * Set to behave inconsistently or its contents to appear to change.
78  * <li>They disallow {@code null} elements. Attempts to create them with
79  * {@code null} elements result in {@code NullPointerException}.
80  * <li>They are serializable if all elements are serializable.
81  * <li>They reject duplicate elements at creation time. Duplicate elements
82  * passed to a static factory method result in {@code IllegalArgumentException}.
83  * <li>The iteration order of set elements is unspecified and is subject to change.
84  * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
85  * Programmers should treat instances that are {@linkplain #equals(Object) equal}
86  * as interchangeable and should not use them for synchronization, or
87  * unpredictable behavior may occur. For example, in a future release,
88  * synchronization may fail. Callers should make no assumptions
89  * about the identity of the returned instances. Factories are free to
90  * create new instances or reuse existing ones.
91  * <li>They are serialized as specified on the
92  * <a href="{@docRoot}/serialized-form.html#java.util.CollSer">Serialized Form</a>
93  * page.
94  * </ul>
95  *
96  * <p>This interface is a member of the
97  * <a href="{@docRoot}/java.base/java/util/package-summary.html#CollectionsFramework">
98  * Java Collections Framework</a>.
99  *
100  * @param <E> the type of elements maintained by this set
101  *
102  * @author  Josh Bloch
103  * @author  Neal Gafter
104  * @see Collection
105  * @see List
106  * @see SortedSet
107  * @see HashSet
108  * @see TreeSet
109  * @see AbstractSet
110  * @see Collections#singleton(java.lang.Object)
111  * @see Collections#EMPTY_SET
112  * @since 1.2
113  */
114 
115 public interface Set<E> extends Collection<E> {
116     // Query Operations
117 
118     /**
119      * Returns the number of elements in this set (its cardinality).  If this
120      * set contains more than {@code Integer.MAX_VALUE} elements, returns
121      * {@code Integer.MAX_VALUE}.
122      *
123      * @return the number of elements in this set (its cardinality)
124      */
size()125     int size();
126 
127     /**
128      * Returns {@code true} if this set contains no elements.
129      *
130      * @return {@code true} if this set contains no elements
131      */
isEmpty()132     boolean isEmpty();
133 
134     /**
135      * Returns {@code true} if this set contains the specified element.
136      * More formally, returns {@code true} if and only if this set
137      * contains an element {@code e} such that
138      * {@code Objects.equals(o, e)}.
139      *
140      * @param o element whose presence in this set is to be tested
141      * @return {@code true} if this set contains the specified element
142      * @throws ClassCastException if the type of the specified element
143      *         is incompatible with this set
144      * (<a href="Collection.html#optional-restrictions">optional</a>)
145      * @throws NullPointerException if the specified element is null and this
146      *         set does not permit null elements
147      * (<a href="Collection.html#optional-restrictions">optional</a>)
148      */
contains(Object o)149     boolean contains(Object o);
150 
151     /**
152      * Returns an iterator over the elements in this set.  The elements are
153      * returned in no particular order (unless this set is an instance of some
154      * class that provides a guarantee).
155      *
156      * @return an iterator over the elements in this set
157      */
iterator()158     Iterator<E> iterator();
159 
160     /**
161      * Returns an array containing all of the elements in this set.
162      * If this set makes any guarantees as to what order its elements
163      * are returned by its iterator, this method must return the
164      * elements in the same order.
165      *
166      * <p>The returned array will be "safe" in that no references to it
167      * are maintained by this set.  (In other words, this method must
168      * allocate a new array even if this set is backed by an array).
169      * The caller is thus free to modify the returned array.
170      *
171      * <p>This method acts as bridge between array-based and collection-based
172      * APIs.
173      *
174      * @return an array containing all the elements in this set
175      */
toArray()176     Object[] toArray();
177 
178     /**
179      * Returns an array containing all of the elements in this set; the
180      * runtime type of the returned array is that of the specified array.
181      * If the set fits in the specified array, it is returned therein.
182      * Otherwise, a new array is allocated with the runtime type of the
183      * specified array and the size of this set.
184      *
185      * <p>If this set fits in the specified array with room to spare
186      * (i.e., the array has more elements than this set), the element in
187      * the array immediately following the end of the set is set to
188      * {@code null}.  (This is useful in determining the length of this
189      * set <i>only</i> if the caller knows that this set does not contain
190      * any null elements.)
191      *
192      * <p>If this set makes any guarantees as to what order its elements
193      * are returned by its iterator, this method must return the elements
194      * in the same order.
195      *
196      * <p>Like the {@link #toArray()} method, this method acts as bridge between
197      * array-based and collection-based APIs.  Further, this method allows
198      * precise control over the runtime type of the output array, and may,
199      * under certain circumstances, be used to save allocation costs.
200      *
201      * <p>Suppose {@code x} is a set known to contain only strings.
202      * The following code can be used to dump the set into a newly allocated
203      * array of {@code String}:
204      *
205      * <pre>
206      *     String[] y = x.toArray(new String[0]);</pre>
207      *
208      * Note that {@code toArray(new Object[0])} is identical in function to
209      * {@code toArray()}.
210      *
211      * @param a the array into which the elements of this set are to be
212      *        stored, if it is big enough; otherwise, a new array of the same
213      *        runtime type is allocated for this purpose.
214      * @return an array containing all the elements in this set
215      * @throws ArrayStoreException if the runtime type of the specified array
216      *         is not a supertype of the runtime type of every element in this
217      *         set
218      * @throws NullPointerException if the specified array is null
219      */
toArray(T[] a)220     <T> T[] toArray(T[] a);
221 
222 
223     // Modification Operations
224 
225     /**
226      * Adds the specified element to this set if it is not already present
227      * (optional operation).  More formally, adds the specified element
228      * {@code e} to this set if the set contains no element {@code e2}
229      * such that
230      * {@code Objects.equals(e, e2)}.
231      * If this set already contains the element, the call leaves the set
232      * unchanged and returns {@code false}.  In combination with the
233      * restriction on constructors, this ensures that sets never contain
234      * duplicate elements.
235      *
236      * <p>The stipulation above does not imply that sets must accept all
237      * elements; sets may refuse to add any particular element, including
238      * {@code null}, and throw an exception, as described in the
239      * specification for {@link Collection#add Collection.add}.
240      * Individual set implementations should clearly document any
241      * restrictions on the elements that they may contain.
242      *
243      * @param e element to be added to this set
244      * @return {@code true} if this set did not already contain the specified
245      *         element
246      * @throws UnsupportedOperationException if the {@code add} operation
247      *         is not supported by this set
248      * @throws ClassCastException if the class of the specified element
249      *         prevents it from being added to this set
250      * @throws NullPointerException if the specified element is null and this
251      *         set does not permit null elements
252      * @throws IllegalArgumentException if some property of the specified element
253      *         prevents it from being added to this set
254      */
add(E e)255     boolean add(E e);
256 
257 
258     /**
259      * Removes the specified element from this set if it is present
260      * (optional operation).  More formally, removes an element {@code e}
261      * such that
262      * {@code Objects.equals(o, e)}, if
263      * this set contains such an element.  Returns {@code true} if this set
264      * contained the element (or equivalently, if this set changed as a
265      * result of the call).  (This set will not contain the element once the
266      * call returns.)
267      *
268      * @param o object to be removed from this set, if present
269      * @return {@code true} if this set contained the specified element
270      * @throws ClassCastException if the type of the specified element
271      *         is incompatible with this set
272      * (<a href="Collection.html#optional-restrictions">optional</a>)
273      * @throws NullPointerException if the specified element is null and this
274      *         set does not permit null elements
275      * (<a href="Collection.html#optional-restrictions">optional</a>)
276      * @throws UnsupportedOperationException if the {@code remove} operation
277      *         is not supported by this set
278      */
remove(Object o)279     boolean remove(Object o);
280 
281 
282     // Bulk Operations
283 
284     /**
285      * Returns {@code true} if this set contains all of the elements of the
286      * specified collection.  If the specified collection is also a set, this
287      * method returns {@code true} if it is a <i>subset</i> of this set.
288      *
289      * @param  c collection to be checked for containment in this set
290      * @return {@code true} if this set contains all of the elements of the
291      *         specified collection
292      * @throws ClassCastException if the types of one or more elements
293      *         in the specified collection are incompatible with this
294      *         set
295      * (<a href="Collection.html#optional-restrictions">optional</a>)
296      * @throws NullPointerException if the specified collection contains one
297      *         or more null elements and this set does not permit null
298      *         elements
299      * (<a href="Collection.html#optional-restrictions">optional</a>),
300      *         or if the specified collection is null
301      * @see    #contains(Object)
302      */
containsAll(Collection<?> c)303     boolean containsAll(Collection<?> c);
304 
305     /**
306      * Adds all of the elements in the specified collection to this set if
307      * they're not already present (optional operation).  If the specified
308      * collection is also a set, the {@code addAll} operation effectively
309      * modifies this set so that its value is the <i>union</i> of the two
310      * sets.  The behavior of this operation is undefined if the specified
311      * collection is modified while the operation is in progress.
312      *
313      * @param  c collection containing elements to be added to this set
314      * @return {@code true} if this set changed as a result of the call
315      *
316      * @throws UnsupportedOperationException if the {@code addAll} operation
317      *         is not supported by this set
318      * @throws ClassCastException if the class of an element of the
319      *         specified collection prevents it from being added to this set
320      * @throws NullPointerException if the specified collection contains one
321      *         or more null elements and this set does not permit null
322      *         elements, or if the specified collection is null
323      * @throws IllegalArgumentException if some property of an element of the
324      *         specified collection prevents it from being added to this set
325      * @see #add(Object)
326      */
addAll(Collection<? extends E> c)327     boolean addAll(Collection<? extends E> c);
328 
329     /**
330      * Retains only the elements in this set that are contained in the
331      * specified collection (optional operation).  In other words, removes
332      * from this set all of its elements that are not contained in the
333      * specified collection.  If the specified collection is also a set, this
334      * operation effectively modifies this set so that its value is the
335      * <i>intersection</i> of the two sets.
336      *
337      * @param  c collection containing elements to be retained in this set
338      * @return {@code true} if this set changed as a result of the call
339      * @throws UnsupportedOperationException if the {@code retainAll} operation
340      *         is not supported by this set
341      * @throws ClassCastException if the class of an element of this set
342      *         is incompatible with the specified collection
343      * (<a href="Collection.html#optional-restrictions">optional</a>)
344      * @throws NullPointerException if this set contains a null element and the
345      *         specified collection does not permit null elements
346      *         (<a href="Collection.html#optional-restrictions">optional</a>),
347      *         or if the specified collection is null
348      * @see #remove(Object)
349      */
retainAll(Collection<?> c)350     boolean retainAll(Collection<?> c);
351 
352     /**
353      * Removes from this set all of its elements that are contained in the
354      * specified collection (optional operation).  If the specified
355      * collection is also a set, this operation effectively modifies this
356      * set so that its value is the <i>asymmetric set difference</i> of
357      * the two sets.
358      *
359      * @param  c collection containing elements to be removed from this set
360      * @return {@code true} if this set changed as a result of the call
361      * @throws UnsupportedOperationException if the {@code removeAll} operation
362      *         is not supported by this set
363      * @throws ClassCastException if the class of an element of this set
364      *         is incompatible with the specified collection
365      * (<a href="Collection.html#optional-restrictions">optional</a>)
366      * @throws NullPointerException if this set contains a null element and the
367      *         specified collection does not permit null elements
368      *         (<a href="Collection.html#optional-restrictions">optional</a>),
369      *         or if the specified collection is null
370      * @see #remove(Object)
371      * @see #contains(Object)
372      */
removeAll(Collection<?> c)373     boolean removeAll(Collection<?> c);
374 
375     /**
376      * Removes all of the elements from this set (optional operation).
377      * The set will be empty after this call returns.
378      *
379      * @throws UnsupportedOperationException if the {@code clear} method
380      *         is not supported by this set
381      */
clear()382     void clear();
383 
384 
385     // Comparison and hashing
386 
387     /**
388      * Compares the specified object with this set for equality.  Returns
389      * {@code true} if the specified object is also a set, the two sets
390      * have the same size, and every member of the specified set is
391      * contained in this set (or equivalently, every member of this set is
392      * contained in the specified set).  This definition ensures that the
393      * equals method works properly across different implementations of the
394      * set interface.
395      *
396      * @param o object to be compared for equality with this set
397      * @return {@code true} if the specified object is equal to this set
398      */
equals(Object o)399     boolean equals(Object o);
400 
401     /**
402      * Returns the hash code value for this set.  The hash code of a set is
403      * defined to be the sum of the hash codes of the elements in the set,
404      * where the hash code of a {@code null} element is defined to be zero.
405      * This ensures that {@code s1.equals(s2)} implies that
406      * {@code s1.hashCode()==s2.hashCode()} for any two sets {@code s1}
407      * and {@code s2}, as required by the general contract of
408      * {@link Object#hashCode}.
409      *
410      * @return the hash code value for this set
411      * @see Object#equals(Object)
412      * @see Set#equals(Object)
413      */
hashCode()414     int hashCode();
415 
416     /**
417      * Creates a {@code Spliterator} over the elements in this set.
418      *
419      * <p>The {@code Spliterator} reports {@link Spliterator#DISTINCT}.
420      * Implementations should document the reporting of additional
421      * characteristic values.
422      *
423      * @implSpec
424      * The default implementation creates a
425      * <em><a href="Spliterator.html#binding">late-binding</a></em> spliterator
426      * from the set's {@code Iterator}.  The spliterator inherits the
427      * <em>fail-fast</em> properties of the set's iterator.
428      * <p>
429      * The created {@code Spliterator} additionally reports
430      * {@link Spliterator#SIZED}.
431      *
432      * @implNote
433      * The created {@code Spliterator} additionally reports
434      * {@link Spliterator#SUBSIZED}.
435      *
436      * @return a {@code Spliterator} over the elements in this set
437      * @since 1.8
438      */
439     @Override
spliterator()440     default Spliterator<E> spliterator() {
441         return Spliterators.spliterator(this, Spliterator.DISTINCT);
442     }
443 
444     /**
445      * Returns an unmodifiable set containing zero elements.
446      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
447      *
448      * @param <E> the {@code Set}'s element type
449      * @return an empty {@code Set}
450      *
451      * @since 9
452      */
453     @SuppressWarnings("unchecked")
of()454     static <E> Set<E> of() {
455         return (Set<E>) ImmutableCollections.EMPTY_SET;
456     }
457 
458     /**
459      * Returns an unmodifiable set containing one element.
460      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
461      *
462      * @param <E> the {@code Set}'s element type
463      * @param e1 the single element
464      * @return a {@code Set} containing the specified element
465      * @throws NullPointerException if the element is {@code null}
466      *
467      * @since 9
468      */
of(E e1)469     static <E> Set<E> of(E e1) {
470         return new ImmutableCollections.Set12<>(e1);
471     }
472 
473     /**
474      * Returns an unmodifiable set containing two elements.
475      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
476      *
477      * @param <E> the {@code Set}'s element type
478      * @param e1 the first element
479      * @param e2 the second element
480      * @return a {@code Set} containing the specified elements
481      * @throws IllegalArgumentException if the elements are duplicates
482      * @throws NullPointerException if an element is {@code null}
483      *
484      * @since 9
485      */
of(E e1, E e2)486     static <E> Set<E> of(E e1, E e2) {
487         return new ImmutableCollections.Set12<>(e1, e2);
488     }
489 
490     /**
491      * Returns an unmodifiable set containing three elements.
492      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
493      *
494      * @param <E> the {@code Set}'s element type
495      * @param e1 the first element
496      * @param e2 the second element
497      * @param e3 the third element
498      * @return a {@code Set} containing the specified elements
499      * @throws IllegalArgumentException if there are any duplicate elements
500      * @throws NullPointerException if an element is {@code null}
501      *
502      * @since 9
503      */
of(E e1, E e2, E e3)504     static <E> Set<E> of(E e1, E e2, E e3) {
505         return new ImmutableCollections.SetN<>(e1, e2, e3);
506     }
507 
508     /**
509      * Returns an unmodifiable set containing four elements.
510      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
511      *
512      * @param <E> the {@code Set}'s element type
513      * @param e1 the first element
514      * @param e2 the second element
515      * @param e3 the third element
516      * @param e4 the fourth element
517      * @return a {@code Set} containing the specified elements
518      * @throws IllegalArgumentException if there are any duplicate elements
519      * @throws NullPointerException if an element is {@code null}
520      *
521      * @since 9
522      */
of(E e1, E e2, E e3, E e4)523     static <E> Set<E> of(E e1, E e2, E e3, E e4) {
524         return new ImmutableCollections.SetN<>(e1, e2, e3, e4);
525     }
526 
527     /**
528      * Returns an unmodifiable set containing five elements.
529      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
530      *
531      * @param <E> the {@code Set}'s element type
532      * @param e1 the first element
533      * @param e2 the second element
534      * @param e3 the third element
535      * @param e4 the fourth element
536      * @param e5 the fifth element
537      * @return a {@code Set} containing the specified elements
538      * @throws IllegalArgumentException if there are any duplicate elements
539      * @throws NullPointerException if an element is {@code null}
540      *
541      * @since 9
542      */
of(E e1, E e2, E e3, E e4, E e5)543     static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5) {
544         return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5);
545     }
546 
547     /**
548      * Returns an unmodifiable set containing six elements.
549      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
550      *
551      * @param <E> the {@code Set}'s element type
552      * @param e1 the first element
553      * @param e2 the second element
554      * @param e3 the third element
555      * @param e4 the fourth element
556      * @param e5 the fifth element
557      * @param e6 the sixth element
558      * @return a {@code Set} containing the specified elements
559      * @throws IllegalArgumentException if there are any duplicate elements
560      * @throws NullPointerException if an element is {@code null}
561      *
562      * @since 9
563      */
of(E e1, E e2, E e3, E e4, E e5, E e6)564     static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
565         return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5,
566                                                e6);
567     }
568 
569     /**
570      * Returns an unmodifiable set containing seven elements.
571      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
572      *
573      * @param <E> the {@code Set}'s element type
574      * @param e1 the first element
575      * @param e2 the second element
576      * @param e3 the third element
577      * @param e4 the fourth element
578      * @param e5 the fifth element
579      * @param e6 the sixth element
580      * @param e7 the seventh element
581      * @return a {@code Set} containing the specified elements
582      * @throws IllegalArgumentException if there are any duplicate elements
583      * @throws NullPointerException if an element is {@code null}
584      *
585      * @since 9
586      */
of(E e1, E e2, E e3, E e4, E e5, E e6, E e7)587     static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
588         return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5,
589                                                e6, e7);
590     }
591 
592     /**
593      * Returns an unmodifiable set containing eight elements.
594      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
595      *
596      * @param <E> the {@code Set}'s element type
597      * @param e1 the first element
598      * @param e2 the second element
599      * @param e3 the third element
600      * @param e4 the fourth element
601      * @param e5 the fifth element
602      * @param e6 the sixth element
603      * @param e7 the seventh element
604      * @param e8 the eighth element
605      * @return a {@code Set} containing the specified elements
606      * @throws IllegalArgumentException if there are any duplicate elements
607      * @throws NullPointerException if an element is {@code null}
608      *
609      * @since 9
610      */
of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8)611     static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
612         return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5,
613                                                e6, e7, e8);
614     }
615 
616     /**
617      * Returns an unmodifiable set containing nine elements.
618      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
619      *
620      * @param <E> the {@code Set}'s element type
621      * @param e1 the first element
622      * @param e2 the second element
623      * @param e3 the third element
624      * @param e4 the fourth element
625      * @param e5 the fifth element
626      * @param e6 the sixth element
627      * @param e7 the seventh element
628      * @param e8 the eighth element
629      * @param e9 the ninth element
630      * @return a {@code Set} containing the specified elements
631      * @throws IllegalArgumentException if there are any duplicate elements
632      * @throws NullPointerException if an element is {@code null}
633      *
634      * @since 9
635      */
of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9)636     static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
637         return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5,
638                                                e6, e7, e8, e9);
639     }
640 
641     /**
642      * Returns an unmodifiable set containing ten elements.
643      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
644      *
645      * @param <E> the {@code Set}'s element type
646      * @param e1 the first element
647      * @param e2 the second element
648      * @param e3 the third element
649      * @param e4 the fourth element
650      * @param e5 the fifth element
651      * @param e6 the sixth element
652      * @param e7 the seventh element
653      * @param e8 the eighth element
654      * @param e9 the ninth element
655      * @param e10 the tenth element
656      * @return a {@code Set} containing the specified elements
657      * @throws IllegalArgumentException if there are any duplicate elements
658      * @throws NullPointerException if an element is {@code null}
659      *
660      * @since 9
661      */
of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10)662     static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
663         return new ImmutableCollections.SetN<>(e1, e2, e3, e4, e5,
664                                                e6, e7, e8, e9, e10);
665     }
666 
667     /**
668      * Returns an unmodifiable set containing an arbitrary number of elements.
669      * See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
670      *
671      * @apiNote
672      * This method also accepts a single array as an argument. The element type of
673      * the resulting set will be the component type of the array, and the size of
674      * the set will be equal to the length of the array. To create a set with
675      * a single element that is an array, do the following:
676      *
677      * <pre>{@code
678      *     String[] array = ... ;
679      *     Set<String[]> list = Set.<String[]>of(array);
680      * }</pre>
681      *
682      * This will cause the {@link Set#of(Object) Set.of(E)} method
683      * to be invoked instead.
684      *
685      * @param <E> the {@code Set}'s element type
686      * @param elements the elements to be contained in the set
687      * @return a {@code Set} containing the specified elements
688      * @throws IllegalArgumentException if there are any duplicate elements
689      * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
690      *
691      * @since 9
692      */
693     @SafeVarargs
694     @SuppressWarnings("varargs")
of(E... elements)695     static <E> Set<E> of(E... elements) {
696         switch (elements.length) { // implicit null check of elements
697             case 0:
698                 @SuppressWarnings("unchecked")
699                 var set = (Set<E>) ImmutableCollections.EMPTY_SET;
700                 return set;
701             case 1:
702                 return new ImmutableCollections.Set12<>(elements[0]);
703             case 2:
704                 return new ImmutableCollections.Set12<>(elements[0], elements[1]);
705             default:
706                 return new ImmutableCollections.SetN<>(elements);
707         }
708     }
709 
710     /**
711      * Returns an <a href="#unmodifiable">unmodifiable Set</a> containing the elements
712      * of the given Collection. The given Collection must not be null, and it must not
713      * contain any null elements. If the given Collection contains duplicate elements,
714      * an arbitrary element of the duplicates is preserved. If the given Collection is
715      * subsequently modified, the returned Set will not reflect such modifications.
716      *
717      * @implNote
718      * If the given Collection is an <a href="#unmodifiable">unmodifiable Set</a>,
719      * calling copyOf will generally not create a copy.
720      *
721      * @param <E> the {@code Set}'s element type
722      * @param coll a {@code Collection} from which elements are drawn, must be non-null
723      * @return a {@code Set} containing the elements of the given {@code Collection}
724      * @throws NullPointerException if coll is null, or if it contains any nulls
725      * @since 10
726      */
727     @SuppressWarnings("unchecked")
copyOf(Collection<? extends E> coll)728     static <E> Set<E> copyOf(Collection<? extends E> coll) {
729         if (coll instanceof ImmutableCollections.AbstractImmutableSet) {
730             return (Set<E>)coll;
731         } else {
732             return (Set<E>)Set.of(new HashSet<>(coll).toArray());
733         }
734     }
735 }
736