mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
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:
parent
6d82950756
commit
f4db9575d1
10 changed files with 675 additions and 153 deletions
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright (c) 2012, 2016, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2017, 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
|
||||
|
@ -116,6 +116,8 @@ public final class Collectors {
|
|||
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED,
|
||||
Collector.Characteristics.IDENTITY_FINISH));
|
||||
static final Set<Collector.Characteristics> CH_NOID = Collections.emptySet();
|
||||
static final Set<Collector.Characteristics> CH_UNORDERED_NOID
|
||||
= Collections.unmodifiableSet(EnumSet.of(Collector.Characteristics.UNORDERED));
|
||||
|
||||
private Collectors() { }
|
||||
|
||||
|
@ -278,6 +280,26 @@ public final class Collectors {
|
|||
CH_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter
|
||||
* order. The returned Collector disallows null values and will throw
|
||||
* {@code NullPointerException} if it is presented with a null value.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @return a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../List.html#unmodifiable">unmodifiable List</a> in encounter order
|
||||
* @since 10
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>
|
||||
Collector<T, ?, List<T>> toUnmodifiableList() {
|
||||
return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
|
||||
(left, right) -> { left.addAll(right); return left; },
|
||||
list -> (List<T>)List.of(list.toArray()),
|
||||
CH_NOID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into a
|
||||
* new {@code Set}. There are no guarantees on the type, mutability,
|
||||
|
@ -305,6 +327,36 @@ public final class Collectors {
|
|||
CH_UNORDERED_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../Set.html#unmodifiable">unmodifiable Set</a>. The returned
|
||||
* Collector disallows null values and will throw {@code NullPointerException}
|
||||
* if it is presented with a null value. If the input contains duplicate elements,
|
||||
* an arbitrary element of the duplicates is preserved.
|
||||
*
|
||||
* <p>This is an {@link Collector.Characteristics#UNORDERED unordered}
|
||||
* Collector.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @return a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../Set.html#unmodifiable">unmodifiable Set</a>
|
||||
* @since 10
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T>
|
||||
Collector<T, ?, Set<T>> toUnmodifiableSet() {
|
||||
return new CollectorImpl<>((Supplier<Set<T>>) HashSet::new, Set::add,
|
||||
(left, right) -> {
|
||||
if (left.size() < right.size()) {
|
||||
right.addAll(left); return right;
|
||||
} else {
|
||||
left.addAll(right); return left;
|
||||
}
|
||||
},
|
||||
set -> (Set<T>)Set.of(set.toArray()),
|
||||
CH_UNORDERED_NOID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that concatenates the input elements into a
|
||||
* {@code String}, in encounter order.
|
||||
|
@ -1353,7 +1405,7 @@ public final class Collectors {
|
|||
* <p>If the mapped keys contain duplicates (according to
|
||||
* {@link Object#equals(Object)}), an {@code IllegalStateException} is
|
||||
* thrown when the collection operation is performed. If the mapped keys
|
||||
* may have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
|
||||
* might have duplicates, use {@link #toMap(Function, Function, BinaryOperator)}
|
||||
* instead.
|
||||
*
|
||||
* <p>There are no guarantees on the type, mutability, serializability,
|
||||
|
@ -1410,6 +1462,45 @@ public final class Collectors {
|
|||
CH_ID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
|
||||
* whose keys and values are the result of applying the provided
|
||||
* mapping functions to the input elements.
|
||||
*
|
||||
* <p>If the mapped keys contain duplicates (according to
|
||||
* {@link Object#equals(Object)}), an {@code IllegalStateException} is
|
||||
* thrown when the collection operation is performed. If the mapped keys
|
||||
* might have duplicates, use {@link #toUnmodifiableMap(Function, Function, BinaryOperator)}
|
||||
* to handle merging of the values.
|
||||
*
|
||||
* <p>The returned Collector disallows null keys and values. If either mapping function
|
||||
* returns null, {@code NullPointerException} will be thrown.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @param <K> the output type of the key mapping function
|
||||
* @param <U> the output type of the value mapping function
|
||||
* @param keyMapper a mapping function to produce keys, must be non-null
|
||||
* @param valueMapper a mapping function to produce values, must be non-null
|
||||
* @return a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../Map.html#unmodifiable">unmodifiable Map</a>, whose keys and values
|
||||
* are the result of applying the provided mapping functions to the input elements
|
||||
* @throws NullPointerException if either keyMapper or valueMapper is null
|
||||
*
|
||||
* @see #toUnmodifiableMap(Function, Function, BinaryOperator)
|
||||
* @since 10
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper) {
|
||||
Objects.requireNonNull(keyMapper, "keyMapper");
|
||||
Objects.requireNonNull(valueMapper, "valueMapper");
|
||||
return collectingAndThen(
|
||||
toMap(keyMapper, valueMapper),
|
||||
map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates elements into a
|
||||
* {@code Map} whose keys and values are the result of applying the provided
|
||||
|
@ -1473,6 +1564,51 @@ public final class Collectors {
|
|||
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../Map.html#unmodifiable">unmodifiable Map</a>,
|
||||
* whose keys and values are the result of applying the provided
|
||||
* mapping functions to the input elements.
|
||||
*
|
||||
* <p>If the mapped
|
||||
* keys contain duplicates (according to {@link Object#equals(Object)}),
|
||||
* the value mapping function is applied to each equal element, and the
|
||||
* results are merged using the provided merging function.
|
||||
*
|
||||
* <p>The returned Collector disallows null keys and values. If either mapping function
|
||||
* returns null, {@code NullPointerException} will be thrown.
|
||||
*
|
||||
* @param <T> the type of the input elements
|
||||
* @param <K> the output type of the key mapping function
|
||||
* @param <U> the output type of the value mapping function
|
||||
* @param keyMapper a mapping function to produce keys, must be non-null
|
||||
* @param valueMapper a mapping function to produce values, must be non-null
|
||||
* @param mergeFunction a merge function, used to resolve collisions between
|
||||
* values associated with the same key, as supplied
|
||||
* to {@link Map#merge(Object, Object, BiFunction)},
|
||||
* must be non-null
|
||||
* @return a {@code Collector} that accumulates the input elements into an
|
||||
* <a href="../Map.html#unmodifiable">unmodifiable Map</a>, whose keys and values
|
||||
* are the result of applying the provided mapping functions to the input elements
|
||||
* @throws NullPointerException if the keyMapper, valueMapper, or mergeFunction is null
|
||||
*
|
||||
* @see #toUnmodifiableMap(Function, Function)
|
||||
* @since 10
|
||||
*/
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
public static <T, K, U>
|
||||
Collector<T, ?, Map<K,U>> toUnmodifiableMap(Function<? super T, ? extends K> keyMapper,
|
||||
Function<? super T, ? extends U> valueMapper,
|
||||
BinaryOperator<U> mergeFunction) {
|
||||
Objects.requireNonNull(keyMapper, "keyMapper");
|
||||
Objects.requireNonNull(valueMapper, "valueMapper");
|
||||
Objects.requireNonNull(mergeFunction, "mergeFunction");
|
||||
return collectingAndThen(
|
||||
toMap(keyMapper, valueMapper, mergeFunction, HashMap::new),
|
||||
map -> (Map<K,U>)Map.ofEntries(map.entrySet().toArray(new Map.Entry[0])));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@code Collector} that accumulates elements into a
|
||||
* {@code Map} whose keys and values are the result of applying the provided
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue