news 2026/3/24 20:00:34

316. Java Stream API - 收集为 Map:使用 Collectors.toMap()

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
316. Java Stream API - 收集为 Map:使用 Collectors.toMap()

文章目录

  • 316. Java Stream API - 收集为 Map:使用 `Collectors.toMap()`
      • ✨ 基本使用方式:两个函数搞定键和值
      • ✅ 示例:构建用户缓存
      • ❗️处理重复 Key:传入合并函数
      • 🧰 高级用法:指定 Map 实现类
      • 🧵 多线程收集:使用 `toConcurrentMap()`
      • 📚 总结对比
      • 🗣 小结语句(可课堂口播):

316. Java Stream API - 收集为 Map:使用Collectors.toMap()

除了前面讲过的groupingBy()收集器,我们还有一个强大的伙伴:Collectors.toMap(),用于将 Stream 中的元素转换为一个真正的键值对映射(Map)。这一方法非常适合构建缓存、索引或者快速查找的数据结构。


✨ 基本使用方式:两个函数搞定键和值

我们先来看基础语法:

Map<K,V>map=stream.collect(Collectors.toMap(keyMapper,valueMapper));
  • keyMapper:用于生成 Map 的 key。
  • valueMapper:用于生成 Map 的 value。

⚠️ 注意:如果多个元素产生相同的 key,会抛出IllegalStateException,除非你提供合并逻辑。


✅ 示例:构建用户缓存

假设你有一个User类,每个用户有一个id,你想用id作为 key,把用户缓存起来。

recordUser(longid,Stringname){}List<User>users=List.of(newUser(1L,"Mary"),newUser(2L,"James"),newUser(3L,"Patricia"),newUser(4L,"Michael"));Map<Long,User>userCache=users.stream().collect(Collectors.toMap(User::id,Function.identity()));System.out.println("Map size = "+userCache.size());System.out.println("Keys = "+userCache.keySet());

运行结果:

Mapsize=4Keys=[1,2,3,4]
  • User::id生成 key
  • Function.identity()返回元素本身作为 value

🎯 用途:常用于缓存索引表的构建。


❗️处理重复 Key:传入合并函数

如果你预期多个元素会生成相同的 key,你需要提供一个合并函数BinaryOperator)告诉 Java 如何合并值。

我们来看下面这个示例:

Collection<String>strings=List.of("one","two","three","four","five","six","seven","eight","nine","ten","eleven","twelve");Map<Integer,String>map=strings.stream().collect(Collectors.toMap(str->str.length(),// key: 字符串长度str->str,// value: 字符串本身(s1,s2)->s1+", "+s2));// 合并函数:拼接字符串map.forEach((key,value)->System.out.println(key+" :: "+value));

输出结果:

3::one,two,six,ten4::four,five,nine5::three,seven,eight6::eleven,twelve

📌 如果不提供合并函数,会在 key 冲突时抛出异常。


🧰 高级用法:指定 Map 实现类

默认情况下,toMap()返回一个HashMap。但你也可以使用第四个参数传入你想要的 Map 类型:

TreeMap<Integer,String>sortedMap=strings.stream().collect(Collectors.toMap(str->str.length(),str->str,(s1,s2)->s1+", "+s2,TreeMap::new));System.out.println(sortedMap);

🧾 输出将是按 key 排序的:

{3=one,two,six,ten,4=four,five,nine,5=three,seven,eight,6=eleven,twelve}

🧵 多线程收集:使用toConcurrentMap()

你还可以使用Collectors.toConcurrentMap()来构建线程安全的 Map,适合并行流或多线程场景:

ConcurrentMap<Long,User>userCache=users.parallelStream().collect(Collectors.toConcurrentMap(User::id,Function.identity()));

💡 实际类型通常是ConcurrentHashMap,但规范不保证具体实现。


📚 总结对比

Collector用途支持重复 Key下游收集器控制 Map 类型
groupingBy()分组、统计、分类✅ 可选✅ 可选
toMap()映射、缓存、索引❌(需手动合并)✅ 可选
toConcurrentMap()并发安全映射❌(需手动合并)✅ 默认并发 Map

🗣 小结语句(可课堂口播):

🔊 “我们用groupingBy()做统计图、做分类。但当你需要构建键值结构,比如缓存、索引表,就轮到toMap()登场了!要注意 key 冲突的处理,避免运行时炸锅!”

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/3/20 4:50:49

基于Spring AI构建智能客服系统的架构设计与实战避坑指南

基于Spring AI构建智能客服系统的架构设计与实战避坑指南 背景痛点&#xff1a;规则引擎的“天花板” 去年双十一&#xff0c;公司老客服系统直接“罢工”。 背景是&#xff1a;运营同学在后台又双叒叕加了一条“如果用户同时提到‘退货’和‘优惠券’&#xff0c;就先安抚再补…

作者头像 李华
网站建设 2026/3/19 6:39:52

Docker 27网络策略必须立即升级的3个信号:DNS劫持、跨命名空间逃逸、hostPort绕过——现在修复还来得及

第一章&#xff1a;Docker 27网络策略精细化控制的演进与危机本质 Docker 27&#xff08;即 Docker Engine v27.x&#xff09;标志着容器网络模型从粗粒度隔离向策略驱动型微边界管控的关键跃迁。其核心变革在于将传统桥接网络的静态 IP 分配、端口映射与防火墙规则&#xff0c…

作者头像 李华
网站建设 2026/3/24 19:01:10

Docker镜像国产化签名验签体系落地实践(GB/T 39786-2021合规版):SM2证书嵌入、国密算法镜像校验与自动化流水线集成

第一章&#xff1a;Docker镜像国产化签名验签体系落地实践&#xff08;GB/T 39786-2021合规版&#xff09;&#xff1a;SM2证书嵌入、国密算法镜像校验与自动化流水线集成为满足《信息安全技术 信息系统密码应用基本要求》&#xff08;GB/T 39786-2021&#xff09;对容器镜像完…

作者头像 李华