--- old/src/java.base/share/classes/java/util/List.java 2015-11-05 17:45:23.000000000 -0800
+++ new/src/java.base/share/classes/java/util/List.java 2015-11-05 17:45:23.000000000 -0800
@@ -87,6 +87,19 @@
* Such exceptions are marked as "optional" in the specification for this
* interface.
*
+ *
The {@link List#of(Object...) List.of()} factory methods
+ * provide a convenient way to create immutable lists. The {@code List}
+ * instances created by these methods have the following characteristics:
+ *
+ *
+ *
They cannot be modified. Attempts to modify them result in
+ * an {@code UnsupportedOperationException}.
+ *
They disallow null elements. Attempts to create them with
+ * null elements result in {@code NullPointerException}.
+ *
They are serializable if all elements are serializable.
+ *
+ *
*
This interface is a member of the
*
* Java Collections Framework.
@@ -731,4 +744,313 @@
default Spliterator spliterator() {
return Spliterators.spliterator(this, Spliterator.ORDERED);
}
+
+ /**
+ * Creates an immutable list containing zero elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @return the newly created list
+ *
+ * @since 1.9
+ */
+ static List of() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Creates an immutable list containing one element.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the single list element
+ * @return the newly created list
+ * @throws NullPointerException if the element is null
+ *
+ * @since 1.9
+ */
+ static List of(E e1) {
+ return Collections.singletonList(Objects.requireNonNull(e1));
+ }
+
+ /**
+ * Creates an immutable list containing two elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List of(E e1, E e2) {
+ return Collections.unmodifiableList(
+ Arrays.asList(Objects.requireNonNull(e1),
+ Objects.requireNonNull(e2)));
+ }
+
+ /**
+ * Creates an immutable list containing three elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List of(E e1, E e2, E e3) {
+ return Collections.unmodifiableList(
+ Arrays.asList(Objects.requireNonNull(e1),
+ Objects.requireNonNull(e2),
+ Objects.requireNonNull(e3)));
+ }
+
+ /**
+ * Creates an immutable list containing four elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing five elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @param e5 the fifth list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing six elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @param e5 the fifth list element
+ * @param e6 the sixth list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing seven elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @param e5 the fifth list element
+ * @param e6 the sixth list element
+ * @param e7 the seventh list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing eight elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @param e5 the fifth list element
+ * @param e6 the sixth list element
+ * @param e7 the seventh list element
+ * @param e8 the eighth list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing nine elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @param e5 the fifth list element
+ * @param e6 the sixth list element
+ * @param e7 the seventh list element
+ * @param e8 the eighth list element
+ * @param e9 the ninth list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing ten elements.
+ *
+ * See Immutable List Factory Methods for details.
+ *
+ * @param the list's element type
+ * @param e1 the first list element
+ * @param e2 the second list element
+ * @param e3 the third list element
+ * @param e4 the fourth list element
+ * @param e5 the fifth list element
+ * @param e6 the sixth list element
+ * @param e7 the seventh list element
+ * @param e8 the eighth list element
+ * @param e9 the ninth list element
+ * @param e10 the tenth list element
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static List 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)));
+ }
+
+ /**
+ * Creates an immutable list containing an arbitrary number of elements.
+ *
+ * See Immutable List Factory Methods 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:
+ *
+ *
{@code
+ * String[] array = ... ;
+ * List list = List.of(array);
+ * }
+ *
+ * This will cause the {@link List#of(Object) List.of(E)} method
+ * to be invoked instead.
+ *
+ * @param the list's element type
+ * @param es the elements to be contained in the list
+ * @return the newly created list
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ @SafeVarargs
+ @SuppressWarnings("varargs")
+ static List of(E... es) {
+ for (E e : es) {
+ Objects.requireNonNull(e);
+ }
+ // NOTE: this can allow a null element to slip through
+ return Collections.unmodifiableList(Arrays.asList(es));
+ }
}
--- old/src/java.base/share/classes/java/util/Map.java 2015-11-05 17:45:24.000000000 -0800
+++ new/src/java.base/share/classes/java/util/Map.java 2015-11-05 17:45:24.000000000 -0800
@@ -110,6 +110,23 @@
* Implementations may optionally handle the self-referential scenario, however
* most current implementations do not do so.
*
+ *
The {@link Map#of() Map.of()} and
+ * {@link Map#ofEntries(Map.Entry...) Map.ofEntries()}
+ * factory methods provide a convenient way to create immutable maps.
+ * The {@code Map}
+ * instances created by these methods have the following characteristics:
+ *
+ *
+ *
They cannot be modified. Attempts to modify them result in
+ * an {@code UnsupportedOperationException}.
+ *
They disallow null keys and values. Attempts to create them with
+ * null keys or values result in {@code NullPointerException}.
+ *
They are serializable if all keys and values are serializable.
+ *
They reject duplicate keys at creation time. Duplicate keys
+ * passed to a factory method result in {@code IllegalArgumentException}.
+ *
+ *
*
This interface is a member of the
*
* Java Collections Framework.
@@ -1233,4 +1250,452 @@
}
return newValue;
}
+
+ /**
+ * Creates an immutable map containing zero mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the map's value type
+ * @return the newly created map
+ *
+ * @since 1.9
+ */
+ static Map of() {
+ return Collections.emptyMap();
+ }
+
+ /**
+ * Creates an immutable map containing a single mapping.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the map's value type
+ * @param k1 the mapping's key
+ * @param v1 the mapping's value
+ * @return the newly created map
+ * @throws NullPointerException if the key or the value is null
+ *
+ * @since 1.9
+ */
+ static Map of(K k1, V v1) {
+ return Collections.singletonMap(Objects.requireNonNull(k1), Objects.requireNonNull(v1));
+ }
+
+ /**
+ * Creates an immutable map containing two mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if the keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map of(K k1, V v1, K k2, V v2) {
+ Map map = new HashMap<>(3);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing three mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map of(K k1, V v1, K k2, V v2, K k3, V v3) {
+ Map map = new HashMap<>(5);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing four mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
+ Map map = new HashMap<>(6);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing five mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
+ Map map = new HashMap<>(7);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing six mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map 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 map = new HashMap<>(9);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing seven mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map 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 map = new HashMap<>(10);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing eight mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map 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 map = new HashMap<>(11);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing nine mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map 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 map = new HashMap<>(13);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing ten mappings.
+ * See Immutable Map Factory Methods for details.
+ *
+ * @param the map's key type
+ * @param the 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 the newly created map
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any key or value is null
+ *
+ * @since 1.9
+ */
+ static Map 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 map = new HashMap<>(14);
+ 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);
+ }
+
+ /**
+ * Creates an immutable map containing keys and values from the given entries.
+ *
+ * @apiNote
+ * It is convenient to create the map entries using the {@link Map#entry Map.entry()} method.
+ * For example,
+ *
+ *
+ *
+ * @param the map's key type
+ * @param the map's value type
+ * @param entries the keys and values with which the map is populated
+ * @return the newly created {@code Map}
+ * @throws IllegalArgumentException if any keys are duplicates
+ * @throws NullPointerException if any entry, key, or value is null
+ *
+ * @see Map#entry Map.entry()
+ * @since 1.9
+ */
+ @SafeVarargs
+ @SuppressWarnings("varargs")
+ static Map ofEntries(Entry... entries) {
+ Map map = new HashMap<>(entries.length * 4 / 3 + 1);
+ for (Entry e : entries) {
+ Objects.requireNonNull(e);
+ map.put(Objects.requireNonNull(e.getKey()), Objects.requireNonNull(e.getValue()));
+ }
+ if (map.size() != entries.length) {
+ throw new IllegalArgumentException("duplicate elements");
+ }
+ return Collections.unmodifiableMap(map);
+ }
+
+ /**
+ * Creates 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 key and the value must not be null. Calling {@link Entry#setValue Entry.setValue()}
+ * on the returned {@code Entry} results in an {@code UnsupportedOperationException}
+ * being thrown. The returned {@code Entry} is not guaranteed to be serializable.
+ *
+ *
The returned {@code Entry} is a value-based
+ * class; use of identity-sensitive operations (including reference equality
+ * ({@code ==}), identity hash code, or synchronization) on any returned values
+ * may have unpredictable results and should be avoided.
+ *
+ * @param the key's type
+ * @param the value's type
+ * @param k the key
+ * @param v the value
+ * @return the new {@code Entry}
+ * @throws NullPointerException if the key or value is null
+ *
+ * @see Map#ofEntries Map.ofEntries()
+ * @since 1.9
+ */
+ static Entry entry(K k, V v) {
+ // KeyValueHolder checks for nulls
+ return new KeyValueHolder<>(k, v);
+ }
}
--- old/src/java.base/share/classes/java/util/Set.java 2015-11-05 17:45:25.000000000 -0800
+++ new/src/java.base/share/classes/java/util/Set.java 2015-11-05 17:45:25.000000000 -0800
@@ -63,6 +63,21 @@
* Such exceptions are marked as "optional" in the specification for this
* interface.
*
+ *
The {@link Set#of(Object...) Set.of()} factory methods
+ * provide a convenient way to create immutable sets. The {@code Set}
+ * instances created by these methods have the following characteristics:
+ *
+ *
+ *
They cannot be modified. Attempts to modify them result in
+ * an {@code UnsupportedOperationException}.
+ *
They disallow null elements. Attempts to create them with
+ * null elements result in {@code NullPointerException}.
+ *
They are serializable if all elements are serializable.
+ *
They reject duplicate elements at creation time. Duplicate elements
+ * passed to a factory method result in {@code IllegalArgumentException}.
+ *
+ *
*
This interface is a member of the
*
* Java Collections Framework.
@@ -410,4 +425,342 @@
default Spliterator spliterator() {
return Spliterators.spliterator(this, Spliterator.DISTINCT);
}
+
+ /**
+ * Creates an immutable set containing zero elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @return the newly created set
+ *
+ * @since 1.9
+ */
+ static Set of() {
+ return Collections.emptySet();
+ }
+
+ /**
+ * Creates an immutable set containing one element.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the single set element
+ * @return the newly created set
+ * @throws NullPointerException if the element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1) {
+ return Collections.singleton(Objects.requireNonNull(e1));
+ }
+
+ /**
+ * Creates an immutable set containing two elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if the elements are duplicates
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2) {
+ Set set = new HashSet<>(Arrays.asList(Objects.requireNonNull(e1),
+ Objects.requireNonNull(e2)));
+ if (set.size() != 2) {
+ throw new IllegalArgumentException("duplicate elements");
+ }
+ return Collections.unmodifiableSet(set);
+ }
+
+ /**
+ * Creates an immutable set containing three elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing four elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing five elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @param e5 the fifth set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4, E e5) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing six elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @param e5 the fifth set element
+ * @param e6 the sixth set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing seven elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @param e5 the fifth set element
+ * @param e6 the sixth set element
+ * @param e7 the seventh set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing eight elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @param e5 the fifth set element
+ * @param e6 the sixth set element
+ * @param e7 the seventh set element
+ * @param e8 the eighth set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing nine elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @param e5 the fifth set element
+ * @param e6 the sixth set element
+ * @param e7 the seventh set element
+ * @param e8 the eighth set element
+ * @param e9 the ninth set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing ten elements.
+ * See Immutable Set Factory Methods for details.
+ *
+ * @param the set's element type
+ * @param e1 the first set element
+ * @param e2 the second set element
+ * @param e3 the third set element
+ * @param e4 the fourth set element
+ * @param e5 the fifth set element
+ * @param e6 the sixth set element
+ * @param e7 the seventh set element
+ * @param e8 the eighth set element
+ * @param e9 the ninth set element
+ * @param e10 the tenth set element
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ static Set of(E e1, E e2, E e3, E e4, E e5, E e6, E e7, E e8, E e9, E e10) {
+ Set 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);
+ }
+
+ /**
+ * Creates an immutable set containing an arbitrary number of elements.
+ * See Immutable Set Factory Methods 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:
+ *
+ *
{@code
+ * String[] array = ... ;
+ * Set list = Set.of(array);
+ * }
+ *
+ * This will cause the {@link Set#of(Object) Set.of(E)} method
+ * to be invoked instead.
+ *
+ * @param the set's element type
+ * @param es the elements to be contained in the set
+ * @return the newly created set
+ * @throws IllegalArgumentException if there are any duplicate elements
+ * @throws NullPointerException if an element is null
+ *
+ * @since 1.9
+ */
+ @SafeVarargs
+ @SuppressWarnings("varargs")
+ static Set of(E... es) {
+ for (E e : es) {
+ Objects.requireNonNull(e);
+ }
+ // NOTE: this can allow a null element to slip through
+ Set set = new HashSet<>(Arrays.asList(es));
+ if (set.size() != es.length) {
+ throw new IllegalArgumentException("duplicate elements");
+ }
+ return Collections.unmodifiableSet(set);
+ }
}
--- old/test/TEST.groups 2015-11-05 17:45:28.000000000 -0800
+++ new/test/TEST.groups 2015-11-05 17:45:28.000000000 -0800
@@ -758,3 +758,9 @@
-:needs_compact3 \
-:needs_jre \
-:needs_jdk
+
+jep269 = \
+ java/util/Collection/MOAT.java \
+ java/util/Collection/SetFactories.java \
+ java/util/List/ListFactories.java \
+ java/util/Map/MapFactories.java
--- old/test/java/util/Collection/MOAT.java 2015-11-05 17:45:29.000000000 -0800
+++ new/test/java/util/Collection/MOAT.java 2015-11-05 17:45:29.000000000 -0800
@@ -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());
@@ -178,6 +193,70 @@
equal(singletonMap.size(), 1);
testMap(singletonMap);
testImmutableMap(singletonMap);
+
+ // Unmodifiable List
+ testEmptyList(List.of());
+ for (List list : Arrays.asList(
+ List.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);
+ }
+
+ // Unmodifiable Set
+ testEmptySet(Set.of());
+ for (Set set : Arrays.asList(
+ Set.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);
+ }
+
+ // Unmodifiable Map
+
+ @SuppressWarnings("unchecked")
+ Map.Entry[] ea = (Map.Entry[])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 map : Arrays.asList(
+ Map.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 c) {
@@ -190,6 +269,17 @@
check(c.containsAll(new ArrayList()));
}
+ private static void checkUnique(Set s) {
+ for (Integer i : s) {
+ int count = 0;
+ for (Integer j : s) {
+ if (Objects.equals(i,j))
+ ++count;
+ }
+ check(count == 1);
+ }
+ }
+
private static void testEmptyCollection(Collection c) {
check(c.isEmpty());
equal(c.size(), 0);
@@ -330,19 +420,19 @@
}
private static boolean supportsAdd(Collection 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 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)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 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 2015-11-05 17:45:30.000000000 -0800
+++ new/src/java.base/share/classes/java/util/KeyValueHolder.java 2015-11-05 17:45:30.000000000 -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.
+ *
+ *
This is a value-based
+ * 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.
+ *
+ * This class differs from AbstractMap.SimpleImmutableEntry in the following ways:
+ * it is not serializable, and its key and value must be non-null.
+ *
+ * @param the key type
+ * @param the value type
+ *
+ * @see Map#ofEntries Map.ofEntries()
+ * @since 1.9
+ */
+final class KeyValueHolder implements Map.Entry {
+ 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;
+ }
+}
--- /dev/null 2015-11-05 17:45:31.000000000 -0800
+++ new/test/java/util/Collection/SetFactories.java 2015-11-05 17:45:31.000000000 -0800
@@ -0,0 +1,270 @@
+/*
+ * 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 act, Set exp) {
+ return new Object[] { act, exp };
+ }
+
+ static Set hashSetOf(String... args) {
+ return new HashSet<>(Arrays.asList(args));
+ }
+
+ @DataProvider(name="empty")
+ public Iterator