jdk/src/java.base/share/classes/java/util/Set.java
changeset 34527 e3caf3a43d09
parent 32108 aa5490a167ee
child 37802 91fc9ac7b8b3
--- a/jdk/src/java.base/share/classes/java/util/Set.java	Tue Dec 08 16:43:58 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Set.java	Tue Dec 08 13:48:22 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -63,6 +63,29 @@
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
+ * <h2><a name="immutable">Immutable Set Static Factory Methods</a></h2>
+ * <p>The {@link Set#of(Object...) Set.of()} static factory methods
+ * provide a convenient way to create immutable sets. The {@code Set}
+ * instances created by these methods have the following characteristics:
+ *
+ * <ul>
+ * <li>They are <em>structurally immutable</em>. Elements cannot be added or
+ * removed. Attempts to do so result in {@code UnsupportedOperationException}.
+ * However, if the contained elements are themselves mutable, this may cause the
+ * Set to behave inconsistently or its contents to appear to change.
+ * <li>They disallow {@code null} elements. Attempts to create them with
+ * {@code null} elements result in {@code NullPointerException}.
+ * <li>They are serializable if all elements are serializable.
+ * <li>They reject duplicate elements at creation time. Duplicate elements
+ * passed to a static factory method result in {@code IllegalArgumentException}.
+ * <li>The iteration order of set elements is unspecified and is subject to change.
+ * <li>They are <a href="../lang/doc-files/ValueBased.html">value-based</a>.
+ * Callers should make no assumptions about the identity of the returned instances.
+ * Factories are free to create new instances or reuse existing ones. Therefore,
+ * identity-sensitive operations on these instances (reference equality ({@code ==}),
+ * identity hash code, and synchronization) are unreliable and should be avoided.
+ * </ul>
+ *
  * <p>This interface is a member of the
  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
  * Java Collections Framework</a>.
@@ -410,4 +433,341 @@
     default Spliterator<E> spliterator() {
         return Spliterators.spliterator(this, Spliterator.DISTINCT);
     }
+
+    /**
+     * Returns an immutable set containing zero elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @return an empty {@code Set}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of() {
+        return Collections.emptySet();
+    }
+
+    /**
+     * Returns an immutable set containing one element.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the single element
+     * @return a {@code Set} containing the specified element
+     * @throws NullPointerException if the element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1) {
+        return Collections.singleton(Objects.requireNonNull(e1));
+    }
+
+    /**
+     * Returns an immutable set containing two elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if the elements are duplicates
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2)));
+        if (set.size() != 2) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing three elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3)));
+        if (set.size() != 3) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing four elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4)));
+        if (set.size() != 4) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing five elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5)));
+        if (set.size() != 5) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing six elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6)));
+        if (set.size() != 6) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing seven elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7)));
+        if (set.size() != 7) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing eight elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7),
+                                                 Objects.requireNonNull(e8)));
+        if (set.size() != 8) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing nine elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @param e9 the ninth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> Set<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7),
+                                                 Objects.requireNonNull(e8),
+                                                 Objects.requireNonNull(e9)));
+        if (set.size() != 9) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing ten elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @param e4 the fourth element
+     * @param e5 the fifth element
+     * @param e6 the sixth element
+     * @param e7 the seventh element
+     * @param e8 the eighth element
+     * @param e9 the ninth element
+     * @param e10 the tenth element
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    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) {
+        Set<E> set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+                                                 Objects.requireNonNull(e2),
+                                                 Objects.requireNonNull(e3),
+                                                 Objects.requireNonNull(e4),
+                                                 Objects.requireNonNull(e5),
+                                                 Objects.requireNonNull(e6),
+                                                 Objects.requireNonNull(e7),
+                                                 Objects.requireNonNull(e8),
+                                                 Objects.requireNonNull(e9),
+                                                 Objects.requireNonNull(e10)));
+        if (set.size() != 10) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
+
+    /**
+     * Returns an immutable set containing an arbitrary number of elements.
+     * See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
+     *
+     * @apiNote
+     * This method also accepts a single array as an argument. The element type of
+     * the resulting set will be the component type of the array, and the size of
+     * the set will be equal to the length of the array. To create a set with
+     * a single element that is an array, do the following:
+     *
+     * <pre>{@code
+     *     String[] array = ... ;
+     *     Set<String[]> list = Set.<String[]>of(array);
+     * }</pre>
+     *
+     * This will cause the {@link Set#of(Object) Set.of(E)} method
+     * to be invoked instead.
+     *
+     * @param <E> the {@code Set}'s element type
+     * @param elements the elements to be contained in the set
+     * @return a {@code Set} containing the specified elements
+     * @throws IllegalArgumentException if there are any duplicate elements
+     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
+     *
+     * @since 9
+     */
+    @SafeVarargs
+    static <E> Set<E> of(E... elements) {
+        for (E e : elements) { // throws NPE if es is null
+            Objects.requireNonNull(e);
+        }
+        @SuppressWarnings("varargs")
+        Set<E> set = new HashSet<>(Arrays.asList(elements));
+        if (set.size() != elements.length) {
+            throw new IllegalArgumentException("duplicate elements");
+        }
+        return Collections.unmodifiableSet(set);
+    }
 }