> toMap(Function super T, ? extends K> keyMapper,
Function super T, ? extends U> valueMapper) {
return new CollectorImpl<>(HashMap::new,
uniqKeysMapAccumulator(keyMapper, valueMapper),
uniqKeysMapMerger(),
CH_ID);
}
/**
* Returns a {@code Collector} that accumulates the input elements into an
* unmodifiable Map,
* whose keys and values are the result of applying the provided
* mapping functions to the input elements.
*
* 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.
*
*
The returned Collector disallows null keys and values. If either mapping function
* returns null, {@code NullPointerException} will be thrown.
*
* @param the type of the input elements
* @param the output type of the key mapping function
* @param 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
* unmodifiable Map, 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
Collector> 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)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
* mapping functions to the input elements.
*
* 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.
*
*
There are no guarantees on the type, mutability, serializability,
* or thread-safety of the {@code Map} returned.
*
* @apiNote
* There are multiple ways to deal with collisions between multiple elements
* mapping to the same key. The other forms of {@code toMap} simply use
* a merge function that throws unconditionally, but you can easily write
* more flexible merge policies. For example, if you have a stream
* of {@code Person}, and you want to produce a "phone book" mapping name to
* address, but it is possible that two persons have the same name, you can
* do as follows to gracefully deal with these collisions, and produce a
* {@code Map} mapping names to a concatenated list of addresses:
*
{@code
* Map phoneBook
* = people.stream().collect(
* toMap(Person::getName,
* Person::getAddress,
* (s, a) -> s + ", " + a));
* }
*
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If it is
* not required that results are merged into the {@code Map} in encounter
* order, using {@link #toConcurrentMap(Function, Function, BinaryOperator)}
* may offer better parallel performance.
*
* @param the type of the input elements
* @param the output type of the key mapping function
* @param the output type of the value mapping function
* @param keyMapper a mapping function to produce keys
* @param valueMapper a mapping function to produce values
* @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)}
* @return a {@code Collector} which collects elements into a {@code Map}
* whose keys are the result of applying a key mapping function to the input
* elements, and whose values are the result of applying a value mapping
* function to all input elements equal to the key and combining them
* using the merge function
*
* @see #toMap(Function, Function)
* @see #toMap(Function, Function, BinaryOperator, Supplier)
* @see #toConcurrentMap(Function, Function, BinaryOperator)
*/
public static
Collector> toMap(Function super T, ? extends K> keyMapper,
Function super T, ? extends U> valueMapper,
BinaryOperator mergeFunction) {
return toMap(keyMapper, valueMapper, mergeFunction, HashMap::new);
}
/**
* Returns a {@code Collector} that accumulates the input elements into an
* unmodifiable Map,
* whose keys and values are the result of applying the provided
* mapping functions to the input elements.
*
* 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.
*
*
The returned Collector disallows null keys and values. If either mapping function
* returns null, {@code NullPointerException} will be thrown.
*
* @param the type of the input elements
* @param the output type of the key mapping function
* @param 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
* unmodifiable Map, 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
Collector> toUnmodifiableMap(Function super T, ? extends K> keyMapper,
Function super T, ? extends U> valueMapper,
BinaryOperator mergeFunction) {
Objects.requireNonNull(keyMapper, "keyMapper");
Objects.requireNonNull(valueMapper, "valueMapper");
Objects.requireNonNull(mergeFunction, "mergeFunction");
return collectingAndThen(
toMap(keyMapper, valueMapper, mergeFunction, HashMap::new),
map -> (Map)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
* mapping functions to the input elements.
*
* 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. The {@code Map}
* is created by a provided supplier function.
*
* @implNote
* The returned {@code Collector} is not concurrent. For parallel stream
* pipelines, the {@code combiner} function operates by merging the keys
* from one map into another, which can be an expensive operation. If it is
* not required that results are merged into the {@code Map} in encounter
* order, using {@link #toConcurrentMap(Function, Function, BinaryOperator, Supplier)}
* may offer better parallel performance.
*
* @param the type of the input elements
* @param