< prev index next >

src/java.base/share/classes/java/util/Map.java

Print this page
rev 14011 : Change @since 1.9 to @since 9.
rev 14012 : Add disclaimer about mutable elements.
rev 14013 : Fix typos.

*** 108,117 **** --- 108,136 ---- * indirectly contains itself. This includes the {@code clone()}, * {@code equals()}, {@code hashCode()} and {@code toString()} methods. * 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 cannot be modified. Attempts to modify them result in + * an {@code UnsupportedOperationException}. + * <li>They are truly immutable only if the contained keys and values are themselves + * immutable. If a key or value is mutated, the behavior of the map is unspecified. + * <li>They disallow null keys and values. Attempts to create them with + * 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}. + * </ul> + * * <p>This interface is a member of the * <a href="{@docRoot}/../technotes/guides/collections/index.html"> * Java Collections Framework</a>. * * @param <K> the type of keys maintained by this map
*** 1231,1236 **** --- 1250,1705 ---- } else { put(key, newValue); } return newValue; } + + /** + * Creates an immutable map containing zero mappings. + * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> the map's value type + * @return the newly created map + * + * @since 9 + */ + static <K,V> Map<K,V> of() { + return Collections.emptyMap(); + } + + /** + * Creates an immutable map containing a single mapping. + * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 9 + */ + static <K,V> Map<K,V> of(K k1, V v1) { + return Collections.singletonMap(Objects.requireNonNull(k1), Objects.requireNonNull(v1)); + } + + /** + * Creates an immutable map containing two mappings. + * See <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 9 + */ + static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2) { + Map<K,V> 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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 <a href="#immutable">Immutable Map Static Factory Methods</a> for details. + * + * @param <K> the map's key type + * @param <V> 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 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); + 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. + * 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 map's key type + * @param <V> 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, or if + * the {@code entries} array is 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) { + 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. + * + * <p>The returned {@code Entry} 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 any returned values + * may have unpredictable results and should be avoided. + * + * @param <K> the key's type + * @param <V> 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 9 + */ + static <K,V> Entry<K,V> entry(K k, V v) { + // KeyValueHolder checks for nulls + return new KeyValueHolder<>(k, v); + } }
< prev index next >