8139232: JEP-269 initial API and skeleton implementations
authorsmarks
Tue, 08 Dec 2015 13:48:22 -0800
changeset 34527 e3caf3a43d09
parent 34526 f1f852f5f477
child 34528 279258fb670b
8139232: JEP-269 initial API and skeleton implementations Reviewed-by: psandoz, rriggs
jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
jdk/src/java.base/share/classes/java/util/List.java
jdk/src/java.base/share/classes/java/util/Map.java
jdk/src/java.base/share/classes/java/util/Set.java
jdk/test/java/util/Collection/MOAT.java
jdk/test/java/util/Collection/SetFactories.java
jdk/test/java/util/List/ListFactories.java
jdk/test/java/util/Map/MapFactories.java
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/src/java.base/share/classes/java/util/KeyValueHolder.java	Tue Dec 08 13:48:22 2015 -0800
@@ -0,0 +1,126 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.util;
+
+/**
+ * An immutable container for a key and a value, suitable for use
+ * in creating and populating {@code Map} instances.
+ *
+ * <p>This is a <a href="../lang/doc-files/ValueBased.html">value-based</a>
+ * class; use of identity-sensitive operations (including reference equality
+ * ({@code ==}), identity hash code, or synchronization) on instances of
+ * {@code KeyValueHolder} may have unpredictable results and should be avoided.
+ *
+ * @apiNote
+ * This class is not public. Instances can be created using the
+ * {@link Map#entry Map.entry(k, v)} factory method, which is public.
+ *
+ * <p>This class differs from AbstractMap.SimpleImmutableEntry in the following ways:
+ * it is not serializable, it is final, and its key and value must be non-null.
+ *
+ * @param <K> the key type
+ * @param <V> the value type
+ *
+ * @see Map#ofEntries Map.ofEntries()
+ * @since 9
+ */
+final class KeyValueHolder<K,V> implements Map.Entry<K,V> {
+    final K key;
+    final V value;
+
+    KeyValueHolder(K k, V v) {
+        key = Objects.requireNonNull(k);
+        value = Objects.requireNonNull(v);
+    }
+
+    /**
+     * Gets the key from this holder.
+     *
+     * @return the key
+     */
+    @Override
+    public K getKey() {
+        return key;
+    }
+
+    /**
+     * Gets the value from this holder.
+     *
+     * @return the value
+     */
+    @Override
+    public V getValue() {
+        return value;
+    }
+
+    /**
+     * Throws {@link UnsupportedOperationException}.
+     *
+     * @param value ignored
+     * @return never returns normally
+     */
+    @Override
+    public V setValue(V value) {
+        throw new UnsupportedOperationException("not supported");
+    }
+
+    /**
+     * Compares the specified object with this entry for equality.
+     * Returns {@code true} if the given object is also a map entry and
+     * the two entries' keys and values are equal. Note that key and
+     * value are non-null, so equals() can be called safely on them.
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof Map.Entry))
+            return false;
+        Map.Entry<?,?> e = (Map.Entry<?,?>)o;
+        return key.equals(e.getKey()) && value.equals(e.getValue());
+    }
+
+    /**
+     * Returns the hash code value for this map entry. The hash code
+     * is {@code key.hashCode() ^ value.hashCode()}. Note that key and
+     * value are non-null, so hashCode() can be called safely on them.
+     */
+    @Override
+    public int hashCode() {
+        return key.hashCode() ^ value.hashCode();
+    }
+
+    /**
+     * Returns a String representation of this map entry.  This
+     * implementation returns the string representation of this
+     * entry's key followed by the equals character ("{@code =}")
+     * followed by the string representation of this entry's value.
+     *
+     * @return a String representation of this map entry
+     */
+    @Override
+    public String toString() {
+        return key + "=" + value;
+    }
+}
--- a/jdk/src/java.base/share/classes/java/util/List.java	Tue Dec 08 16:43:58 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/List.java	Tue Dec 08 13:48:22 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2014, 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
@@ -87,6 +87,28 @@
  * Such exceptions are marked as "optional" in the specification for this
  * interface.
  *
+ * <h2><a name="immutable">Immutable List Static Factory Methods</a></h2>
+ * <p>The {@link List#of(Object...) List.of()} static factory methods
+ * provide a convenient way to create immutable lists. The {@code List}
+ * instances created by these methods have the following characteristics:
+ *
+ * <ul>
+ * <li>They are <em>structurally immutable</em>. Elements cannot be added, removed,
+ * or replaced. Attempts to do so result in {@code UnsupportedOperationException}.
+ * However, if the contained elements are themselves mutable,
+ * this may cause the List's 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>The order of elements in the list is the same as the order of the
+ * provided arguments, or of the elements in the provided array.
+ * <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>.
@@ -731,4 +753,312 @@
     default Spliterator<E> spliterator() {
         return Spliterators.spliterator(this, Spliterator.ORDERED);
     }
+
+    /**
+     * Returns an immutable list containing zero elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @return an empty {@code List}
+     *
+     * @since 9
+     */
+    static <E> List<E> of() {
+        return Collections.emptyList();
+    }
+
+    /**
+     * Returns an immutable list containing one element.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the single element
+     * @return a {@code List} containing the specified element
+     * @throws NullPointerException if the element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1) {
+        return Collections.singletonList(Objects.requireNonNull(e1));
+    }
+
+    /**
+     * Returns an immutable list containing two elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2)));
+    }
+
+    /**
+     * Returns an immutable list containing three elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param e1 the first element
+     * @param e2 the second element
+     * @param e3 the third element
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3)));
+    }
+
+    /**
+     * Returns an immutable list containing four elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4)));
+    }
+
+    /**
+     * Returns an immutable list containing five elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5)));
+    }
+
+    /**
+     * Returns an immutable list containing six elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6)));
+    }
+
+    /**
+     * Returns an immutable list containing seven elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+        return Collections.unmodifiableList(
+            Arrays.asList(Objects.requireNonNull(e1),
+                          Objects.requireNonNull(e2),
+                          Objects.requireNonNull(e3),
+                          Objects.requireNonNull(e4),
+                          Objects.requireNonNull(e5),
+                          Objects.requireNonNull(e6),
+                          Objects.requireNonNull(e7)));
+    }
+
+    /**
+     * Returns an immutable list containing eight elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+        return Collections.unmodifiableList(
+            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)));
+    }
+
+    /**
+     * Returns an immutable list containing nine elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+        return Collections.unmodifiableList(
+            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)));
+    }
+
+    /**
+     * Returns an immutable list containing ten elements.
+     *
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @param <E> the {@code List}'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 List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null}
+     *
+     * @since 9
+     */
+    static <E> List<E> of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
+        return Collections.unmodifiableList(
+            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)));
+    }
+
+    /**
+     * Returns an immutable list containing an arbitrary number of elements.
+     * See <a href="#immutable">Immutable List Static Factory Methods</a> for details.
+     *
+     * @apiNote
+     * This method also accepts a single array as an argument. The element type of
+     * the resulting list will be the component type of the array, and the size of
+     * the list will be equal to the length of the array. To create a list with
+     * a single element that is an array, do the following:
+     *
+     * <pre>{@code
+     *     String[] array = ... ;
+     *     List<String[]> list = List.<String[]>of(array);
+     * }</pre>
+     *
+     * This will cause the {@link List#of(Object) List.of(E)} method
+     * to be invoked instead.
+     *
+     * @param <E> the {@code List}'s element type
+     * @param elements the elements to be contained in the list
+     * @return a {@code List} containing the specified elements
+     * @throws NullPointerException if an element is {@code null} or if the array is {@code null}
+     *
+     * @since 9
+     */
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    static <E> List<E> of(E... elements) {
+        elements = elements.clone(); // throws NPE if es is null
+        for (E e : elements) {
+            Objects.requireNonNull(e);
+        }
+        return Collections.unmodifiableList(Arrays.asList(elements));
+    }
 }
--- a/jdk/src/java.base/share/classes/java/util/Map.java	Tue Dec 08 16:43:58 2015 -0800
+++ b/jdk/src/java.base/share/classes/java/util/Map.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
@@ -110,6 +110,31 @@
  * Implementations may optionally handle the self-referential scenario, however
  * most current implementations do not do so.
  *
+ * <h2><a name="immutable">Immutable Map Static Factory Methods</a></h2>
+ * <p>The {@link Map#of() Map.of()} and
+ * {@link Map#ofEntries(Map.Entry...) Map.ofEntries()}
+ * static factory methods provide a convenient way to create immutable maps.
+ * The {@code Map}
+ * instances created by these methods have the following characteristics:
+ *
+ * <ul>
+ * <li>They are <em>structurally immutable</em>. Keys and values cannot be added,
+ * removed, or updated. Attempts to do so result in {@code UnsupportedOperationException}.
+ * However, if the contained keys or values are themselves mutable, this may cause the
+ * Map to behave inconsistently or its contents to appear to change.
+ * <li>They disallow {@code null} keys and values. Attempts to create them with
+ * {@code null} keys or values result in {@code NullPointerException}.
+ * <li>They are serializable if all keys and values are serializable.
+ * <li>They reject duplicate keys at creation time. Duplicate keys
+ * passed to a static factory method result in {@code IllegalArgumentException}.
+ * <li>The iteration order of mappings 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>.
@@ -126,7 +151,7 @@
  * @see Set
  * @since 1.2
  */
-public interface Map<K,V> {
+public interface Map<K, V> {
     // Query Operations
 
     /**
@@ -373,7 +398,7 @@
      * @see Map#entrySet()
      * @since 1.2
      */
-    interface Entry<K,V> {
+    interface Entry<K, V> {
         /**
          * Returns the key corresponding to this entry.
          *
@@ -468,7 +493,7 @@
          * @see Comparable
          * @since 1.8
          */
-        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K,V>> comparingByKey() {
+        public static <K extends Comparable<? super K>, V> Comparator<Map.Entry<K, V>> comparingByKey() {
             return (Comparator<Map.Entry<K, V>> & Serializable)
                 (c1, c2) -> c1.getKey().compareTo(c2.getKey());
         }
@@ -485,7 +510,7 @@
          * @see Comparable
          * @since 1.8
          */
-        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K,V>> comparingByValue() {
+        public static <K, V extends Comparable<? super V>> Comparator<Map.Entry<K, V>> comparingByValue() {
             return (Comparator<Map.Entry<K, V>> & Serializable)
                 (c1, c2) -> c1.getValue().compareTo(c2.getValue());
         }
@@ -1233,4 +1258,465 @@
         }
         return newValue;
     }
+
+    /**
+     * Returns an immutable map containing zero mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @return an empty {@code Map}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of() {
+        return Collections.emptyMap();
+    }
+
+    /**
+     * Returns an immutable map containing a single mapping.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the mapping's key
+     * @param v1 the mapping's value
+     * @return a {@code Map} containing the specified mapping
+     * @throws NullPointerException if the key or the value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1) {
+        return Collections.singletonMap(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+    }
+
+    /**
+     * Returns an immutable map containing two mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if the keys are duplicates
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
+        Map<K, V> map = new HashMap<>(3); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        if (map.size() != 2) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing three mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
+        Map<K, V> map = new HashMap<>(5); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        if (map.size() != 3) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing four mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
+        Map<K, V> map = new HashMap<>(6); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        if (map.size() != 4) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing five mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
+        Map<K, V> map = new HashMap<>(7); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        if (map.size() != 5) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing six mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6) {
+        Map<K, V> map = new HashMap<>(9); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        if (map.size() != 6) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing seven mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7) {
+        Map<K, V> map = new HashMap<>(10); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        if (map.size() != 7) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing eight mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @param k8 the eighth mapping's key
+     * @param v8 the eighth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7, K k8, V v8) {
+        Map<K, V> map = new HashMap<>(11); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
+        if (map.size() != 8) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing nine mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @param k8 the eighth mapping's key
+     * @param v8 the eighth mapping's value
+     * @param k9 the ninth mapping's key
+     * @param v9 the ninth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
+        Map<K, V> map = new HashMap<>(13); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
+        map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
+        if (map.size() != 9) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing ten mappings.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param k1 the first mapping's key
+     * @param v1 the first mapping's value
+     * @param k2 the second mapping's key
+     * @param v2 the second mapping's value
+     * @param k3 the third mapping's key
+     * @param v3 the third mapping's value
+     * @param k4 the fourth mapping's key
+     * @param v4 the fourth mapping's value
+     * @param k5 the fifth mapping's key
+     * @param v5 the fifth mapping's value
+     * @param k6 the sixth mapping's key
+     * @param v6 the sixth mapping's value
+     * @param k7 the seventh mapping's key
+     * @param v7 the seventh mapping's value
+     * @param k8 the eighth mapping's key
+     * @param v8 the eighth mapping's value
+     * @param k9 the ninth mapping's key
+     * @param v9 the ninth mapping's value
+     * @param k10 the tenth mapping's key
+     * @param v10 the tenth mapping's value
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any key or value is {@code null}
+     *
+     * @since 9
+     */
+    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
+                               K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
+        Map<K, V> map = new HashMap<>(14); // specify number of buckets to avoid resizing
+        map.put(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+        map.put(Objects.requireNonNull(k2), Objects.requireNonNull(v2));
+        map.put(Objects.requireNonNull(k3), Objects.requireNonNull(v3));
+        map.put(Objects.requireNonNull(k4), Objects.requireNonNull(v4));
+        map.put(Objects.requireNonNull(k5), Objects.requireNonNull(v5));
+        map.put(Objects.requireNonNull(k6), Objects.requireNonNull(v6));
+        map.put(Objects.requireNonNull(k7), Objects.requireNonNull(v7));
+        map.put(Objects.requireNonNull(k8), Objects.requireNonNull(v8));
+        map.put(Objects.requireNonNull(k9), Objects.requireNonNull(v9));
+        map.put(Objects.requireNonNull(k10), Objects.requireNonNull(v10));
+        if (map.size() != 10) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable map containing keys and values extracted from the given entries.
+     * The entries themselves are not stored in the map.
+     * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details.
+     *
+     * @apiNote
+     * It is convenient to create the map entries using the {@link Map#entry Map.entry()} method.
+     * For example,
+     *
+     * <pre>{@code
+     *     import static java.util.Map.entry;
+     *
+     *     Map<Integer,String> map = Map.ofEntries(
+     *         entry(1, "a"),
+     *         entry(2, "b"),
+     *         entry(3, "c"),
+     *         ...
+     *         entry(26, "z"));
+     * }</pre>
+     *
+     * @param <K> the {@code Map}'s key type
+     * @param <V> the {@code Map}'s value type
+     * @param entries {@code Map.Entry}s containing the keys and values from which the map is populated
+     * @return a {@code Map} containing the specified mappings
+     * @throws IllegalArgumentException if there are any duplicate keys
+     * @throws NullPointerException if any entry, key, or value is {@code null}, or if
+     *         the {@code entries} array is {@code null}
+     *
+     * @see Map#entry Map.entry()
+     * @since 9
+     */
+    @SafeVarargs
+    @SuppressWarnings("varargs")
+    static <K, V> Map<K, V> ofEntries(Entry<K, V>... entries) {
+        Map<K, V> map = new HashMap<>(entries.length * 4 / 3 + 1); // throws NPE if entries is null
+        for (Entry<K, V> e : entries) {
+            // next line throws NPE if e is null
+            map.put(Objects.requireNonNull(e.getKey()), Objects.requireNonNull(e.getValue()));
+        }
+        if (map.size() != entries.length) {
+            throw new IllegalArgumentException("duplicate keys");
+        }
+        return Collections.unmodifiableMap(map);
+    }
+
+    /**
+     * Returns an immutable {@link Entry} containing the given key and value.
+     * These entries are suitable for populating {@code Map} instances using the
+     * {@link Map#ofEntries Map.ofEntries()} method.
+     * The {@code Entry} instances created by this method have the following characteristics:
+     *
+     * <ul>
+     * <li>They disallow {@code null} keys and values. Attempts to create them using a {@code null}
+     * key or value result in {@code NullPointerException}.
+     * <li>They are immutable. Calls to {@link Entry#setValue Entry.setValue()}
+     * on a returned {@code Entry} result in {@code UnsupportedOperationException}.
+     * <li>They are not serializable.
+     * <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.
+     * This method is 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>
+     *
+     * @apiNote
+     * For a serializable {@code Entry}, see {@link AbstractMap.SimpleEntry} or
+     * {@link AbstractMap.SimpleImmutableEntry}.
+     *
+     * @param <K> the key's type
+     * @param <V> the value's type
+     * @param k the key
+     * @param v the value
+     * @return an {@code Entry} containing the specified key and value
+     * @throws NullPointerException if the key or value is {@code null}
+     *
+     * @see Map#ofEntries Map.ofEntries()
+     * @since 9
+     */
+    static <K, V> Entry<K, V> entry(K k, V v) {
+        // KeyValueHolder checks for nulls
+        return new KeyValueHolder<>(k, v);
+    }
 }
--- 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);
+    }
 }
--- a/jdk/test/java/util/Collection/MOAT.java	Tue Dec 08 16:43:58 2015 -0800
+++ b/jdk/test/java/util/Collection/MOAT.java	Tue Dec 08 13:48:22 2015 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 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
@@ -58,6 +58,21 @@
 import java.lang.reflect.*;
 
 public class MOAT {
+    // Collections under test must not be initialized to contain this value,
+    // and maps under test must not contain this value as a key.
+    // It's used as a sentinel for absent-element testing.
+    static final int ABSENT_VALUE = 778347983;
+
+    static final Integer[] integerArray;
+    static {
+        Integer[] ia = new Integer[20];
+        // fill with 1..20 inclusive
+        for (int i = 0; i < ia.length; i++) {
+            ia[i] = i + 1;
+        }
+        integerArray = ia;
+    }
+
     public static void realMain(String[] args) {
 
         testCollection(new NewAbstractCollection<Integer>());
@@ -178,6 +193,70 @@
         equal(singletonMap.size(), 1);
         testMap(singletonMap);
         testImmutableMap(singletonMap);
+
+        // Immutable List
+        testEmptyList(List.of());
+        for (List<Integer> list : Arrays.asList(
+                List.<Integer>of(),
+                List.of(1),
+                List.of(1, 2),
+                List.of(1, 2, 3),
+                List.of(1, 2, 3, 4),
+                List.of(1, 2, 3, 4, 5),
+                List.of(1, 2, 3, 4, 5, 6),
+                List.of(1, 2, 3, 4, 5, 6, 7),
+                List.of(1, 2, 3, 4, 5, 6, 7, 8),
+                List.of(1, 2, 3, 4, 5, 6, 7, 8, 9),
+                List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
+                List.of(integerArray))) {
+            testCollection(list);
+            testImmutableList(list);
+        }
+
+        // Immutable Set
+        testEmptySet(Set.of());
+        for (Set<Integer> set : Arrays.asList(
+                Set.<Integer>of(),
+                Set.of(1),
+                Set.of(1, 2),
+                Set.of(1, 2, 3),
+                Set.of(1, 2, 3, 4),
+                Set.of(1, 2, 3, 4, 5),
+                Set.of(1, 2, 3, 4, 5, 6),
+                Set.of(1, 2, 3, 4, 5, 6, 7),
+                Set.of(1, 2, 3, 4, 5, 6, 7, 8),
+                Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9),
+                Set.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10),
+                Set.of(integerArray))) {
+            testCollection(set);
+            testImmutableSet(set);
+        }
+
+        // Immutable Map
+
+        @SuppressWarnings("unchecked")
+        Map.Entry<Integer,Integer>[] ea = (Map.Entry<Integer,Integer>[])new Map.Entry<?,?>[20];
+        for (int i = 0; i < ea.length; i++) {
+            ea[i] = Map.entry(i+1, i+101);
+        }
+
+        testEmptyMap(Map.of());
+        for (Map<Integer,Integer> map : Arrays.asList(
+                Map.<Integer,Integer>of(),
+                Map.of(1, 101),
+                Map.of(1, 101, 2, 202),
+                Map.of(1, 101, 2, 202, 3, 303),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808, 9, 909),
+                Map.of(1, 101, 2, 202, 3, 303, 4, 404, 5, 505, 6, 606, 7, 707, 8, 808, 9, 909, 10, 1010),
+                Map.ofEntries(ea))) {
+            testMap(map);
+            testImmutableMap(map);
+        }
     }
 
     private static void checkContainsSelf(Collection<Integer> c) {
@@ -190,6 +269,17 @@
         check(c.containsAll(new ArrayList<Integer>()));
     }
 
+    private static void checkUnique(Set<Integer> s) {
+        for (Integer i : s) {
+            int count = 0;
+            for (Integer j : s) {
+                if (Objects.equals(i,j))
+                    ++count;
+            }
+            check(count == 1);
+        }
+    }
+
     private static <T> void testEmptyCollection(Collection<T> c) {
         check(c.isEmpty());
         equal(c.size(), 0);
@@ -330,19 +420,19 @@
     }
 
     private static boolean supportsAdd(Collection<Integer> c) {
-        try { check(c.add(778347983)); }
+        try { check(c.add(ABSENT_VALUE)); }
         catch (UnsupportedOperationException t) { return false; }
         catch (Throwable t) { unexpected(t); }
 
         try {
-            check(c.contains(778347983));
-            check(c.remove(778347983));
+            check(c.contains(ABSENT_VALUE));
+            check(c.remove(ABSENT_VALUE));
         } catch (Throwable t) { unexpected(t); }
         return true;
     }
 
     private static boolean supportsRemove(Collection<Integer> c) {
-        try { check(! c.remove(19134032)); }
+        try { check(! c.remove(ABSENT_VALUE)); }
         catch (UnsupportedOperationException t) { return false; }
         catch (Throwable t) { unexpected(t); }
         return true;
@@ -359,6 +449,7 @@
             checkContainsSelf(c);
             checkContainsEmpty(c);
             check(c.size() != 0 ^ c.isEmpty());
+            check(! c.contains(ABSENT_VALUE));
 
             {
                 int size = 0;
@@ -366,6 +457,10 @@
                 check(c.size() == size);
             }
 
+            if (c instanceof Set) {
+                checkUnique((Set<Integer>)c);
+            }
+
             check(c.toArray().length == c.size());
             check(c.toArray().getClass() == Object[].class
                   ||
@@ -861,6 +956,20 @@
         checkFunctionalInvariants(m.keySet());
         checkFunctionalInvariants(m.values());
         check(m.size() != 0 ^ m.isEmpty());
+        check(! m.containsKey(ABSENT_VALUE));
+
+        if (m instanceof Serializable) {
+            //System.out.printf("Serializing %s%n", m.getClass().getName());
+            try {
+                Object clone = serialClone(m);
+                equal(m instanceof Serializable,
+                      clone instanceof Serializable);
+                equal(m, clone);
+            } catch (Error xxx) {
+                if (! (xxx.getCause() instanceof NotSerializableException))
+                    throw xxx;
+            }
+        }
     }
 
     private static void testMap(Map<Integer,Integer> m) {
@@ -910,13 +1019,13 @@
         // We're asking for .equals(...) semantics
         if (m instanceof IdentityHashMap) return false;
 
-        try { check(m.put(778347983,12735) == null); }
+        try { check(m.put(ABSENT_VALUE,12735) == null); }
         catch (UnsupportedOperationException t) { return false; }
         catch (Throwable t) { unexpected(t); }
 
         try {
-            check(m.containsKey(778347983));
-            check(m.remove(778347983) != null);
+            check(m.containsKey(ABSENT_VALUE));
+            check(m.remove(ABSENT_VALUE) != null);
         } catch (Throwable t) { unexpected(t); }
         return true;
     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Collection/SetFactories.java	Tue Dec 08 13:48:22 2015 -0800
@@ -0,0 +1,275 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+import static org.testng.Assert.assertEquals;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on Set.
+ * @run testng SetFactories
+ */
+
+
+public class SetFactories {
+
+    static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
+    static final String[] stringArray;
+    static {
+        String[] sa = new String[NUM_STRINGS];
+        for (int i = 0; i < NUM_STRINGS; i++) {
+            sa[i] = String.valueOf((char)('a' + i));
+        }
+        stringArray = sa;
+    }
+
+    static Object[] a(Set<String> act, Set<String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    static Set<String> hashSetOf(String... args) {
+        return new HashSet<>(Arrays.asList(args));
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            // actual, expected
+            a(Set.of(), Collections.emptySet())
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    public Iterator<Object[]> nonempty() {
+        return Arrays.asList(
+            // actual, expected
+            a(   Set.of("a"),
+              hashSetOf("a")),
+            a(   Set.of("a", "b"),
+              hashSetOf("a", "b")),
+            a(   Set.of("a", "b", "c"),
+              hashSetOf("a", "b", "c")),
+            a(   Set.of("a", "b", "c", "d"),
+              hashSetOf("a", "b", "c", "d")),
+            a(   Set.of("a", "b", "c", "d", "e"),
+              hashSetOf("a", "b", "c", "d", "e")),
+            a(   Set.of("a", "b", "c", "d", "e", "f"),
+              hashSetOf("a", "b", "c", "d", "e", "f")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g", "h")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i")),
+            a(   Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+              hashSetOf("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+            a(   Set.of(stringArray),
+              hashSetOf(stringArray))
+        ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAdd(Set<String> act, Set<String> exp) {
+        act.add("x");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(Set<String> act, Set<String> exp) {
+        act.remove(act.iterator().next());
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(Set<String> act, Set<String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed2() {
+        Set<String> set = Set.of("a", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed3() {
+        Set<String> set = Set.of("a", "b", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed4() {
+        Set<String> set = Set.of("a", "b", "c", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed5() {
+        Set<String> set = Set.of("a", "b", "c", "d", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed6() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed7() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed8() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "g", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed9() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "g", "h", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowed10() {
+        Set<String> set = Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "a");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupsDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = array[1];
+        Set<String> set = Set.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed1() {
+        Set.of((String)null); // force one-arg overload
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2a() {
+        Set.of("a", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2b() {
+        Set.of(null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed3() {
+        Set.of("a", "b", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed4() {
+        Set.of("a", "b", "c", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed5() {
+        Set.of("a", "b", "c", "d", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed6() {
+        Set.of("a", "b", "c", "d", "e", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed7() {
+        Set.of("a", "b", "c", "d", "e", "f", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed8() {
+        Set.of("a", "b", "c", "d", "e", "f", "g", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed9() {
+        Set.of("a", "b", "c", "d", "e", "f", "g", "h", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed10() {
+        Set.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = null;
+        Set.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        Set.of((Object[])null);
+    }
+
+    @Test(dataProvider="all")
+    public void serialEquality(Set<String> act, Set<String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        Set<String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.close();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/List/ListFactories.java	Tue Dec 08 13:48:22 2015 -0800
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static java.util.Arrays.asList;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on List.
+ * @run testng ListFactories
+ */
+
+public class ListFactories {
+
+    static final int NUM_STRINGS = 20; // should be larger than the largest fixed-arg overload
+    static final String[] stringArray;
+    static {
+        String[] sa = new String[NUM_STRINGS];
+        for (int i = 0; i < NUM_STRINGS; i++) {
+            sa[i] = String.valueOf((char)('a' + i));
+        }
+        stringArray = sa;
+    }
+
+    // returns array of [actual, expected]
+    static Object[] a(List<String> act, List<String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            a(List.of(), Collections.emptyList())
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    public Iterator<Object[]> nonempty() {
+        return asList(
+            a(List.of("a"),
+               asList("a")),
+            a(List.of("a", "b"),
+               asList("a", "b")),
+            a(List.of("a", "b", "c"),
+               asList("a", "b", "c")),
+            a(List.of("a", "b", "c", "d"),
+               asList("a", "b", "c", "d")),
+            a(List.of("a", "b", "c", "d", "e"),
+               asList("a", "b", "c", "d", "e")),
+            a(List.of("a", "b", "c", "d", "e", "f"),
+               asList("a", "b", "c", "d", "e", "f")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g"),
+               asList("a", "b", "c", "d", "e", "f", "g")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i")),
+            a(List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", "j"),
+               asList("a", "b", "c", "d", "e", "f", "g", "h", "i", "j")),
+            a(List.of(stringArray),
+               asList(stringArray))
+        ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAddLast(List<String> act, List<String> exp) {
+        act.add("x");
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotAddFirst(List<String> act, List<String> exp) {
+        act.add(0, "x");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(List<String> act, List<String> exp) {
+        act.remove(0);
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotSet(List<String> act, List<String> exp) {
+        act.set(0, "x");
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(List<String> act, List<String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed1() {
+        List.of((Object)null); // force one-arg overload
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2a() {
+        List.of("a", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed2b() {
+        List.of(null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed3() {
+        List.of("a", "b", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed4() {
+        List.of("a", "b", "c", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed5() {
+        List.of("a", "b", "c", "d", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed6() {
+        List.of("a", "b", "c", "d", "e", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed7() {
+        List.of("a", "b", "c", "d", "e", "f", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed8() {
+        List.of("a", "b", "c", "d", "e", "f", "g", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed9() {
+        List.of("a", "b", "c", "d", "e", "f", "g", "h", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowed10() {
+        List.of("a", "b", "c", "d", "e", "f", "g", "h", "i", null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullDisallowedN() {
+        String[] array = stringArray.clone();
+        array[0] = null;
+        List.of(array);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        List.of((Object[])null);
+    }
+
+    @Test
+    public void ensureArrayCannotModifyList() {
+        String[] array = stringArray.clone();
+        List<String> list = List.of(array);
+        array[0] = "xyzzy";
+        assertEquals(list, Arrays.asList(stringArray));
+    }
+
+    @Test(dataProvider="all")
+    public void serialEquality(List<String> act, List<String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        List<String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.close();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/util/Map/MapFactories.java	Tue Dec 08 13:48:22 2015 -0800
@@ -0,0 +1,380 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.util.AbstractMap;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+/*
+ * @test
+ * @bug 8048330
+ * @summary Test convenience static factory methods on Map.
+ * @run testng MapFactories
+ */
+
+public class MapFactories {
+
+    static final int MAX_ENTRIES = 20; // should be larger than the largest fixed-arg overload
+    static String valueFor(int i) {
+        // the String literal below should be of length MAX_ENTRIES
+        return "abcdefghijklmnopqrst".substring(i, i+1);
+    }
+
+    // for "expected" values
+    Map<Integer,String> genMap(int n) {
+        Map<Integer,String> result = new HashMap<>();
+        for (int i = 0; i < n; i++) {
+            result.put(i, valueFor(i));
+        }
+        return result;
+    }
+
+    // for varargs Map.Entry methods
+    @SuppressWarnings("unchecked")
+    Map.Entry<Integer,String>[] genEntries(int n) {
+        return IntStream.range(0, n)
+            .mapToObj(i -> Map.entry(i, valueFor(i)))
+            .toArray(Map.Entry[]::new);
+    }
+
+    // returns array of [actual, expected]
+    static Object[] a(Map<Integer,String> act, Map<Integer,String> exp) {
+        return new Object[] { act, exp };
+    }
+
+    @DataProvider(name="empty")
+    public Iterator<Object[]> empty() {
+        return Collections.singletonList(
+            a(Map.of(), genMap(0))
+        ).iterator();
+    }
+
+    @DataProvider(name="nonempty")
+    @SuppressWarnings("unchecked")
+    public Iterator<Object[]> nonempty() {
+        return Arrays.asList(
+            a(Map.of(0, "a"), genMap(1)),
+            a(Map.of(0, "a", 1, "b"), genMap(2)),
+            a(Map.of(0, "a", 1, "b", 2, "c"), genMap(3)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d"), genMap(4)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e"), genMap(5)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f"), genMap(6)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g"), genMap(7)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h"), genMap(8)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i"), genMap(9)),
+            a(Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e", 5, "f", 6, "g", 7, "h", 8, "i", 9, "j"), genMap(10)),
+            a(Map.ofEntries(genEntries(MAX_ENTRIES)), genMap(MAX_ENTRIES))
+        ).iterator();
+    }
+
+    @DataProvider(name="all")
+    public Iterator<Object[]> all() {
+        List<Object[]> all = new ArrayList<>();
+        empty().forEachRemaining(all::add);
+        nonempty().forEachRemaining(all::add);
+        return all.iterator();
+    }
+
+    @Test(dataProvider="all", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotPutNew(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.put(-1, "xyzzy");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotPutOld(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.put(0, "a");
+    }
+
+    @Test(dataProvider="nonempty", expectedExceptions=UnsupportedOperationException.class)
+    public void cannotRemove(Map<Integer,String> act, Map<Integer,String> exp) {
+        act.remove(act.keySet().iterator().next());
+    }
+
+    @Test(dataProvider="all")
+    public void contentsMatch(Map<Integer,String> act, Map<Integer,String> exp) {
+        assertEquals(act, exp);
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed2() {
+        Map<Integer, String> map = Map.of(0, "a", 0, "b");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed3() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 0, "c");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed4() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 0, "d");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed5() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 0, "e");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed6() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          0, "f");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed7() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 0, "g");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed8() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 0, "h");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed9() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 0, "i");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowed10() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, "i", 0, "j");
+    }
+
+    @Test(expectedExceptions=IllegalArgumentException.class)
+    public void dupKeysDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[MAX_ENTRIES-1] = Map.entry(0, "xxx");
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed1() {
+        Map<Integer, String> map = Map.of(null, "a");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed1() {
+        Map<Integer, String> map = Map.of(0, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed2() {
+        Map<Integer, String> map = Map.of(0, "a", null, "b");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed2() {
+        Map<Integer, String> map = Map.of(0, "a", 1, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed3() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", null, "c");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed3() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed4() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", null, "d");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed4() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed5() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", null, "e");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed5() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed6() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          null, "f");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed6() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed7() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", null, "g");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed7() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed8() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", null, "h");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed8() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed9() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", null, "i");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed9() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowed10() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, "i", null, "j");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowed10() {
+        Map<Integer, String> map = Map.of(0, "a", 1, "b", 2, "c", 3, "d", 4, "e",
+                                          5, "f", 6, "g", 7, "h", 8, "i", 9, null);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullKeyDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[0] = new AbstractMap.SimpleImmutableEntry(null, "a");
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullValueDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[0] = new AbstractMap.SimpleImmutableEntry(0, null);
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullEntryDisallowedN() {
+        Map.Entry<Integer,String>[] entries = genEntries(MAX_ENTRIES);
+        entries[5] = null;
+        Map<Integer, String> map = Map.ofEntries(entries);
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void nullArrayDisallowed() {
+        Map.ofEntries(null);
+    }
+
+    @Test(dataProvider="all")
+    public void serialEquality(Map<Integer, String> act, Map<Integer, String> exp) {
+        // assume that act.equals(exp) tested elsewhere
+        Map<Integer, String> copy = serialClone(act);
+        assertEquals(act, copy);
+        assertEquals(copy, exp);
+    }
+
+    @SuppressWarnings("unchecked")
+    static <T> T serialClone(T obj) {
+        try {
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            ObjectOutputStream oos = new ObjectOutputStream(baos);
+            oos.writeObject(obj);
+            oos.close();
+            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
+            ObjectInputStream ois = new ObjectInputStream(bais);
+            return (T) ois.readObject();
+        } catch (IOException | ClassNotFoundException e) {
+            throw new AssertionError(e);
+        }
+    }
+
+    // Map.entry() tests
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void entryWithNullKeyDisallowed() {
+        Map.Entry<Integer,String> e = Map.entry(null, "x");
+    }
+
+    @Test(expectedExceptions=NullPointerException.class)
+    public void entryWithNullValueDisallowed() {
+        Map.Entry<Integer,String> e = Map.entry(0, null);
+    }
+
+    @Test
+    public void entryBasicTests() {
+        Map.Entry<String,String> kvh1 = Map.entry("xyzzy", "plugh");
+        Map.Entry<String,String> kvh2 = Map.entry("foobar", "blurfl");
+        Map.Entry<String,String> sie = new AbstractMap.SimpleImmutableEntry("xyzzy", "plugh");
+
+        assertTrue(kvh1.equals(sie));
+        assertTrue(sie.equals(kvh1));
+        assertFalse(kvh2.equals(sie));
+        assertFalse(sie.equals(kvh2));
+        assertEquals(sie.hashCode(), kvh1.hashCode());
+        assertEquals(sie.toString(), kvh1.toString());
+    }
+
+}