Collectors.toMap 的 keyMapper 函数显式决定 Key 类型与值,如 String→Long;需手动处理异常;重复 Key 须提供 mergeFunction(如(v1,v2)->v1);可选 Supplier 指定 Map 实现类(如LinkedHashMap::new)。

使用 Collectors.toMap 时,Key 的类型转换不是“自动”发生的,而是通过你传入的 keyMapper 函数显式完成的。只要 keyMapper 返回目标类型(比如从 String 转为 Long、Integer 或自定义枚举),就能实现 Key 类型的转换。
明确 keyMapper 的作用:决定 Key 的类型和值
keyMapper 是一个 Function,它接收流中每个元素,返回你想要的 Key 对象。这个返回值的类型就是最终 Map 的 Key 类型。
- 若原集合元素是
Person,你想用其id字符串转成Long作 Key,就写:p -> Long.parseLong(p.getId()) - 若想用状态码字符串映射为枚举,可写:
s -> StatusEnum.valueOf(s.getStatus()) - 注意:转换逻辑需自行处理异常(如数字格式错误),否则会抛
RuntimeException
处理重复 Key:避免 IllegalStateException
当多个元素生成相同 Key 时,toMap 默认会抛出异常。必须提供 mergeFunction 来指定冲突策略:
- 保留第一个:
(v1, v2) -> v1 - 保留最后一个:
(v1, v2) -> v2 - 合并值(如拼接字符串):
(v1, v2) -> v1 + "," + v2
指定 Map 实现类(可选但实用)
第三个参数是 Supplier,可用于指定返回的 Map 类型,例如:
- 用
LinkedHashMap::new保持插入顺序 - 用
TreeMap::new实现自然排序或自定义排序(需 Key 实现Comparable或传入 Comparator) - 示例:
Collectors.toMap(k -> Integer.valueOf(k), v -> v, (a,b)->a, LinkedHashMap::new)
完整示例:字符串 ID → Long Key + 自定义对象 Value
假设有 List,其中 User.id 是字符串,希望转为 Map:
Map<long user> userMap = users.stream()
.collect(Collectors.toMap(
u -> Long.parseLong(u.getId()), // keyMapper:String → Long
Function.identity(), // valueMapper:直接用 User 对象
(u1, u2) -> u1, // 冲突时保留第一个
LinkedHashMap::new // 保持插入顺序
));</long>
如果 id 可能为空或非法,建议先过滤或用 Optional 包装转换逻辑,避免运行时崩溃。










