mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-15 21:05:11 +00:00
8139232: JEP-269 initial API and skeleton implementations
Reviewed-by: psandoz, rriggs
This commit is contained in:
parent
b0e22f9603
commit
d42e70fc3c
126
jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
Normal file
126
jdk/src/java.base/share/classes/java/util/KeyValueHolder.java
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
@ -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 @@ import java.util.function.UnaryOperator;
|
||||
* 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 @@ public interface List<E> extends Collection<E> {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ import java.io.Serializable;
|
||||
* 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 @@ import java.io.Serializable;
|
||||
* @see Set
|
||||
* @since 1.2
|
||||
*/
|
||||
public interface Map<K,V> {
|
||||
public interface Map<K, V> {
|
||||
// Query Operations
|
||||
|
||||
/**
|
||||
@ -373,7 +398,7 @@ public interface Map<K,V> {
|
||||
* @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 @@ public interface Map<K,V> {
|
||||
* @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 @@ public interface Map<K,V> {
|
||||
* @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 @@ public interface Map<K,V> {
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 @@ package java.util;
|
||||
* 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 @@ public interface Set<E> extends Collection<E> {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 static java.util.Collections.*;
|
||||
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 @@ public class MOAT {
|
||||
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 @@ public class MOAT {
|
||||
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 @@ public class MOAT {
|
||||
}
|
||||
|
||||
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 @@ public class MOAT {
|
||||
checkContainsSelf(c);
|
||||
checkContainsEmpty(c);
|
||||
check(c.size() != 0 ^ c.isEmpty());
|
||||
check(! c.contains(ABSENT_VALUE));
|
||||
|
||||
{
|
||||
int size = 0;
|
||||
@ -366,6 +457,10 @@ public class MOAT {
|
||||
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 @@ public class MOAT {
|
||||
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 @@ public class MOAT {
|
||||
// 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;
|
||||
}
|
||||
|
||||
275
jdk/test/java/util/Collection/SetFactories.java
Normal file
275
jdk/test/java/util/Collection/SetFactories.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
234
jdk/test/java/util/List/ListFactories.java
Normal file
234
jdk/test/java/util/List/ListFactories.java
Normal file
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
380
jdk/test/java/util/Map/MapFactories.java
Normal file
380
jdk/test/java/util/Map/MapFactories.java
Normal file
@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user