8177290: add copy factory methods for unmodifiable List, Set, Map

8184690: add Collectors for collecting into unmodifiable List, Set, and Map

Reviewed-by: alanb, briangoetz, dholmes, jrose, rriggs, scolebourne
This commit is contained in:
Stuart Marks 2017-12-04 11:50:04 -08:00
parent 6d82950756
commit f4db9575d1
10 changed files with 675 additions and 153 deletions

View file

@ -63,15 +63,16 @@ package java.util;
* Such exceptions are marked as "optional" in the specification for this
* interface.
*
* <h2><a id="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}
* <h2><a id="unmodifiable">Unmodifiable Sets</a></h2>
* <p>The {@link Set#of(Object...) Set.of} and
* {@link Set#copyOf Set.copyOf} static factory methods
* provide a convenient way to create unmodifiable 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. Calling any mutator method will always cause
* {@code UnsupportedOperationException} to be thrown.
* <li>They are <a href="Collection.html#unmodifiable"><i>unmodifiable</i></a>. Elements cannot
* be added or removed. Calling any mutator method on the Set
* will always cause {@code UnsupportedOperationException} to be thrown.
* 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
@ -439,8 +440,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing zero elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing zero elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @return an empty {@code Set}
@ -452,8 +453,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing one element.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing one element.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the single element
@ -467,8 +468,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing two elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing two elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -484,8 +485,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing three elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing three elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -502,8 +503,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing four elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing four elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -521,8 +522,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing five elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing five elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -541,8 +542,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing six elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing six elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -563,8 +564,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing seven elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing seven elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -586,8 +587,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing eight elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing eight elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -610,8 +611,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing nine elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing nine elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -635,8 +636,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing ten elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing ten elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @param <E> the {@code Set}'s element type
* @param e1 the first element
@ -661,8 +662,8 @@ public interface Set<E> extends Collection<E> {
}
/**
* Returns an immutable set containing an arbitrary number of elements.
* See <a href="#immutable">Immutable Set Static Factory Methods</a> for details.
* Returns an unmodifiable set containing an arbitrary number of elements.
* See <a href="#unmodifiable">Unmodifiable Sets</a> for details.
*
* @apiNote
* This method also accepts a single array as an argument. The element type of
@ -700,4 +701,30 @@ public interface Set<E> extends Collection<E> {
return new ImmutableCollections.SetN<>(elements);
}
}
/**
* Returns an <a href="#unmodifiable">unmodifiable Set</a> containing the elements
* of the given Collection. The given Collection must not be null, and it must not
* contain any null elements. If the given Collection contains duplicate elements,
* an arbitrary element of the duplicates is preserved. If the given Collection is
* subsequently modified, the returned Set will not reflect such modifications.
*
* @implNote
* If the given Collection is an <a href="#unmodifiable">unmodifiable Set</a>,
* calling copyOf will generally not create a copy.
*
* @param <E> the {@code Set}'s element type
* @param coll a {@code Collection} from which elements are drawn, must be non-null
* @return a {@code Set} containing the elements of the given {@code Collection}
* @throws NullPointerException if coll is null, or if it contains any nulls
* @since 10
*/
@SuppressWarnings("unchecked")
static <E> Set<E> copyOf(Collection<? extends E> coll) {
if (coll instanceof ImmutableCollections.AbstractImmutableSet) {
return (Set<E>)coll;
} else {
return (Set<E>)Set.of(new HashSet<>(coll).toArray());
}
}
}