Collectors.toMap
Collectors.toMap 是 Java 8 引入的用于将流(Stream)中的元素收集到 Map 中的收集器(Collector)。它有多个重载版本,其中 四个参数的版本 是最完整、最灵活的一种:
public static <T, K, U, M extends Map<K, U>> Collector<T, ?, M> toMap(
Function<? super T, ? extends K> keyMapper,
Function<? super T, ? extends U> valueMapper,
BinaryOperator<U> mergeFunction,
Supplier<M> mapSupplier
)
四个参数详解:
-
keyMapper:- 类型:
Function<? super T, ? extends K> - 作用:将流中的每个元素
T映射为Map的键(K)。 - 示例:
Person::getName(假设流中是Person对象,用名字做 key)
- 类型:
-
valueMapper:- 类型:
Function<? super T, ? extends U> - 作用:将流中的每个元素
T映射为Map的值(U)。 - 示例:
Person::getAge(用年龄做 value)
- 类型:
-
mergeFunction:- 类型:
BinaryOperator<U>(即(U, U) -> U) - 作用:当出现重复键时,如何合并两个值。这是解决键冲突的关键。
- 示例:
(oldValue, newValue) -> oldValue(保留旧值)或(v1, v2) -> v1 + v2(合并数值)
- 类型:
-
mapSupplier:- 类型:
Supplier<M>(返回一个空的Map实例) - 作用:指定要创建的
Map类型(如HashMap、LinkedHashMap、TreeMap等)。 - 示例:
LinkedHashMap::new(保持插入顺序)
- 类型:
使用示例
假设有如下 Person 类:
class Person {
String name;
int age;
// 构造函数、getter 省略
}
示例 1:基本用法(带冲突处理和指定 Map 类型)
List<Person> people = Arrays.asList(
new Person("Alice", 30),
new Person("Bob", 25),
new Person("Alice", 35) // 重复 key "Alice"
);
Map<String, Integer> nameToAge = people.stream()
.collect(Collectors.toMap(
Person::getName, // keyMapper
Person::getAge, // valueMapper
(age1, age2) -> age1, // mergeFunction: 保留第一个
LinkedHashMap::new // mapSupplier: 保持插入顺序
));
结果:
{Alice=30, Bob=25}
示例 2:合并值(如累加)
Map<String, Integer> nameToTotalAge = people.stream()
.collect(Collectors.toMap(
Person::getName,
Person::getAge,
Integer::sum, // 合并时相加
HashMap::new
));
结果:
{Alice=65, Bob=25}
示例 3:使用 TreeMap(按键排序)
Map<String, Integer> sortedMap = people.stream()
.collect(Collectors.toMap(
Person::getName,
Person::getAge,
(v1, v2) -> v1,
TreeMap::new
));
注意事项
- 如果不提供
mergeFunction(即使用三参数版本),遇到重复键会抛出IllegalStateException。 mapSupplier允许你控制Map的具体实现,对性能或顺序有要求时非常有用。- 所有函数参数都不能为
null,否则会抛出NullPointerException。
总结
四参数 Collectors.toMap 提供了完整的控制能力:
- 如何生成 key
- 如何生成 value
- 如何处理 key 冲突
- 使用哪种 Map 实现
适用于各种复杂场景,是流式处理中构建 Map 的强大工具。
本文来自博客园,作者:chuangzhou,转载请注明原文链接:https://www.cnblogs.com/czzz/p/19234250

浙公网安备 33010602011771号