Java中从现有不可变Set扩展并创建新不可变Set的技巧

java中从现有不可变set扩展并创建新不可变set的技巧

本文探讨了如何在Java中优雅地从一个已有的不可变Set创建包含额外元素的新不可变Set,同时避免类型混淆问题。通过深入解析Set.of()的局限性,文章重点介绍了两种基于Java Stream API的解决方案,利用flatMap操作高效地合并元素流,最终使用Collectors.toUnmodifiableSet()生成符合预期的不可变结果集,确保类型一致性和数据完整性。

核心问题:不可变Set的扩展挑战

在Java中,Set.of()方法是创建不可变Set的便捷方式。例如,Set s = Set.of(“a”, “b”, “c”)会生成一个包含字符串”a”、”b”、”c”的不可变Set。然而,当我们需要基于这个已有的不可变Set,并添加一些新的元素来创建一个新的不可变Set时,直观地尝试Set t = Set.of(s, “d”)往往会遇到问题。

Set.of()方法在接收多个参数时,会将每个参数视为一个独立的元素。因此,Set.of(s, “d”)会将整个Set s(即[a, b, c])作为第一个元素,将字符串”d”作为第二个元素,最终生成一个类型为Set的Set,其内容类似[[a, b, c], d]。这显然不是我们想要的结果,我们期望的是一个扁平化的Set,如[a, b, c, d],并且类型仍然是Set。

解决这个问题的关键在于,我们需要将现有Set中的所有元素和新增的元素“扁平化”到一个单一的元素流中,然后再将这些元素收集到一个新的不可变Set中。Java 8引入的Stream API为此提供了强大而灵活的工具。

解决方案:利用Java Stream API

Java Stream API提供了一种声明式处理数据集合的方式,非常适合进行这种集合转换操作。以下是两种基于Stream API的解决方案。

立即学习“Java免费学习笔记(深入)”;

方法一:合并Set流

这种方法的核心思想是创建一个包含所有需要合并的Set的流,然后将这些Set中的元素扁平化为一个单一的元素流。

创建Set流: 使用Stream.of()方法创建一个包含原始Set s 和一个只包含新元素的临时Set(例如Set.of(“d”))的流。扁平化元素: 使用flatMap(Set::stream)操作,将流中的每个Set转换为其元素的流,并将所有这些元素的流合并成一个单一的元素流。收集为不可变Set: 最后,使用collect(Collectors.toUnmodifiableSet())将扁平化后的元素流收集到一个新的不可变Set中。

示例代码:

import java.util.Set;import java.util.stream.Collectors;import java.util.stream.Stream;public class ImmutableSetExtension {    public static void main(String[] args) {        // 原始不可变Set        Set s = Set.of("a", "b", "c");        System.out.println("原始Set s: " + s);        // 方法一:合并Set流        Set t1 = Stream.of(s, Set.of("d", "e")) // 创建包含原始Set和新元素Set的流                               .flatMap(Set::stream)    // 将每个Set的元素扁平化为一个流                               .collect(Collectors.toUnmodifiableSet()); // 收集为新的不可变Set        System.out.println("方法一结果 t1: " + t1); // 输出: [a, b, c, d, e] (顺序可能不同)    }}

输出示例:

原始Set s: [a, b, c]方法一结果 t1: [d, c, b, e, a] // 元素顺序可能因Set实现而异

方法二:合并元素流

此方法更加直接,它首先将原始Set和新元素分别转换为各自的元素流,然后将这些元素流合并。

创建原始Set的元素流: 使用s.stream()获取原始Set s 的元素流。创建新元素的元素流: 使用Stream.of(“d”)(或Stream.of(“d”, “e”)等)创建包含新元素的流。合并元素流的流: 使用Stream.of()创建一个包含这两个元素流的流。扁平化元素: 使用flatMap(Function.identity())(或简写为flatMap(s -> s))操作,将流中的每个元素流(即Stream)直接扁平化为一个单一的Stream。收集为不可变Set: 同样,使用collect(Collectors.toUnmodifiableSet())收集结果。

示例代码:

import java.util.Set;import java.util.function.Function;import java.util.stream.Collectors;import java.util.stream.Stream;public class ImmutableSetExtensionAlt {    public static void main(String[] args) {        // 原始不可变Set        Set s = Set.of("a", "b", "c");        System.out.println("原始Set s: " + s);        // 方法二:合并元素流        Set t2 = Stream.of(s.stream(), Stream.of("d", "e")) // 创建包含两个元素流的流                               .flatMap(Function.identity())         // 将流中的流扁平化为一个流                               .collect(Collectors.toUnmodifiableSet()); // 收集为新的不可变Set        System.out.println("方法二结果 t2: " + t2); // 输出: [a, b, c, d, e] (顺序可能不同)    }}

输出示例:

原始Set s: [a, b, c]方法二结果 t2: [d, c, b, e, a] // 元素顺序可能因Set实现而异

两种方法都能达到相同的目的,选择哪种取决于个人偏好和具体上下文。方法一在处理多个现有Set时可能更直观,而方法二在处理混合了现有Set和零散新元素时同样适用。

注意事项

不可变性保证: Collectors.toUnmodifiableSet()是Java 10引入的方法,它确保了返回的Set是不可变的。尝试修改它将抛出UnsupportedOperationException。如果你的Java版本低于10,可以使用Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet)来达到同样的目的。元素类型一致性: 在整个Stream操作过程中,要确保所有元素的类型都是一致的,否则可能导致编译错误或运行时类型转换异常。性能考量: 对于小型Set,Stream API的开销可以忽略不计。但对于非常大的Set,Stream操作通常是高效的,因为它利用了内部迭代和可能的并行化。Set的无序性: Set是无序的集合,所以输出的元素顺序可能与输入顺序不一致。

总结

当需要从一个不可变Set扩展并创建包含额外元素的新不可变Set时,直接使用Set.of()会导致类型混淆。通过Java Stream API的flatMap操作,我们可以有效地将现有Set的元素和新增元素扁平化到一个单一的元素流中,然后使用Collectors.toUnmodifiableSet()将其收集为一个新的、类型正确的不可变Set。这两种基于Stream的方法都提供了清晰、简洁且高效的解决方案,充分体现了Java函数式编程的优势。

以上就是Java中从现有不可变Set扩展并创建新不可变Set的技巧的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/37102.html

赞 (0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
如何在Linux上安装和配置PHP
上一篇 2026年10月30日 19:12:01
Next.js Image与Tailwind CSS实现高性能视差背景图教程
下一篇 2025年12月23日 08:16:46

相关推荐

  • 【方案分享】第十一届 “中国软件杯”大学生软件设计大赛遥感解译赛道 比赛方案分享

    【方案分享】第十一届 “中国软件杯”大学生软件设计大赛遥感解译赛道 比赛方案分享【方案分享】第十一届 “中国软件杯”大学生软件设计大赛遥感解译赛道 比赛方案分享【方案分享】第十一届 “中国软件杯”大学生软件设计大赛遥感解译赛道 比赛方案分享【方案分享】第十一届 “中国软件杯”大学生软件设计大赛遥感解译赛道 比赛方案分享

    本文围绕遥感变化检测项目展开,参考多个相关项目,指出存在随机bug及解决办法。其在相同训练轮数下精度提升明显,还分享了调参思路,涉及数据集、模型、训练超参、后处理等方面。此外,详述了数据预处理、网络训练、测试、推理等流程,并附相关报错及统计数据。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜索,…

    2026年10月30日 • 用户投稿
    400
  • 如何在IDEA中添加Java外部依赖库

    如何在IDEA中添加Java外部依赖库如何在IDEA中添加Java外部依赖库如何在IDEA中添加Java外部依赖库如何在IDEA中添加Java外部依赖库

    推荐使用Maven或Gradle添加依赖,Maven在pom.xml中配置,Gradle在build.gradle中添加并同步;2. 手动添加JAR需将文件放入lib目录并右键“Add as Library”;3. 通过Project Structure的Dependencies页签可批量添加本地库…

    2026年10月30日 • 用户投稿
    000
  • QQ邮箱网页登录入口 QQ邮箱电脑版登录网址

    QQ邮箱网页登录入口 QQ邮箱电脑版登录网址QQ邮箱网页登录入口 QQ邮箱电脑版登录网址QQ邮箱网页登录入口 QQ邮箱电脑版登录网址QQ邮箱网页登录入口 QQ邮箱电脑版登录网址

    qq邮箱登录页面腾讯qq邮箱官方登录入口在哪里?这是不少网友都关注的,接下来由php小编为大家带来腾讯qq邮箱官方登录入口,感兴趣的网友一起随小编来瞧瞧吧! https://mail.qq.com/ 网页端登录操作步骤 1、打开浏览器,在地址栏输入腾讯QQ邮箱官方网站地址。 2、进入登录界面后,选择…

    2026年10月30日 • 用户投稿
    000
  • 双·11家电市场观察:理性消费时代,品质与体验成破局关键

    双·11家电市场观察:理性消费时代,品质与体验成破局关键双·11家电市场观察:理性消费时代,品质与体验成破局关键双·11家电市场观察:理性消费时代,品质与体验成破局关键双·11家电市场观察:理性消费时代,品质与体验成破局关键

    今年双·11,各大电商平台纷纷简化促销规则,主推“官方立降”“单件直降”等直观优惠方式,旨在降低消费者的决策门槛,提升购物效率与体验。与此同时,随着大促节奏的日常化和高频化,用户逐渐告别盲目囤货,消费行为更加理性,更看重“随时可购”和“高性价比”。在这一趋势下,产品本身的品质与使用体验,成为影响购买…

    2026年10月30日 • 用户投稿
    000
  • PPOCRLabel半自动工具标注自制身份证数据集

    PPOCRLabel半自动工具标注自制身份证数据集PPOCRLabel半自动工具标注自制身份证数据集PPOCRLabel半自动工具标注自制身份证数据集PPOCRLabel半自动工具标注自制身份证数据集

    该项目基于PPOCRLabel半自动化标注工具,使用Python和PyQt5编写,支持多种语言模型,可实现OCR数据高效标注。项目通过代码生成身份证数据集,利用PPOCRLabel标注后用于OCR模型训练,还提供了配置好的环境及相关资料,鼓励用户加入SIG小组共同开发。 ☞☞☞AI 智能聊天, 问答…

    2026年10月30日 • 用户投稿
    100
  • 红果短剧app如何制作特效视频 红果短剧app内置工具创意玩法

    红果短剧App支持通过内置特效模板、关键帧动画、AR面部特效和绿幕抠像四大功能制作视觉冲击力强的短视频,适配iPhone 15 Pro在iOS 18系统下高效创作。 如果您想在红果短剧App中制作具有视觉冲击力的特效视频,可以通过其内置的创意工具实现多样化效果。这些功能专为提升短视频表现力而设计,适…

    2026年10月30日
    100
  • es文件浏览器官网官方下载地址__es文件浏览器官方网址最新入口

    es文件浏览器官网官方下载地址__es文件浏览器官方网址最新入口es文件浏览器官网官方下载地址__es文件浏览器官方网址最新入口es文件浏览器官网官方下载地址__es文件浏览器官方网址最新入口es文件浏览器官网官方下载地址__es文件浏览器官方网址最新入口

    es文件浏览器官方网址是http://www.estrongs.com,用户可通过该官网获取最新版下载信息,软件提供高效文件管理、跨平台数据互通及实用工具集成功能,支持多种设备与云服务。 es文件浏览器官网官方下载地址在哪里?这是不少网友都关注的,接下来由PHP小编为大家带来es文件浏览器官方网址最…

    2026年10月30日 • 用户投稿
    300
  • PS平台将迎一大批经典老游!有的曾是任天堂独占

    PS平台将迎一大批经典老游!有的曾是任天堂独占PS平台将迎一大批经典老游!有的曾是任天堂独占PS平台将迎一大批经典老游!有的曾是任天堂独占PS平台将迎一大批经典老游!有的曾是任天堂独占

    据playstation lifestyle消息,ps玩家将有机会体验到多款经典游戏作品,甚至包含曾经的任天堂独占大作。 Limited Run Games近日公布了一批即将登陆PS5与PS4平台的游戏阵容,其中就包括1992年在红白机上推出的稀有作品《圣铃传说》。这款游戏在北美地区极为罕见,长期被…

    2026年10月30日 • 用户投稿
    200
  • 在Java中如何实现线程间定时任务协作

    在Java中如何实现线程间定时任务协作在Java中如何实现线程间定时任务协作在Java中如何实现线程间定时任务协作在Java中如何实现线程间定时任务协作

    使用ScheduledExecutorService结合volatile变量、CyclicBarrier和BlockingQueue实现线程间定时协作,通过定时调度与同步工具确保多线程按需协调执行任务。 在Java中实现线程间定时任务协作,核心是结合定时调度机制与线程通信手段,确保多个线程能按预定时…

    2026年10月30日 • 用户投稿
    000
  • 最少代码,基于PaddleGAN实现GAN的趣味项目应用

    最少代码,基于PaddleGAN实现GAN的趣味项目应用最少代码,基于PaddleGAN实现GAN的趣味项目应用最少代码,基于PaddleGAN实现GAN的趣味项目应用最少代码,基于PaddleGAN实现GAN的趣味项目应用

    本项目借助PaddleGAN演示6个有趣应用,助开发者快速上手。先介绍GAN含生成网络G和判别网络D,及PaddleGAN的作用。接着说明解压缩或安装PaddleGAN及相关软件的步骤。最后展示人脸生成、人脸卡通化等6个示例的功能、示意图及预测代码。 ☞☞☞AI 智能聊天, 问答助手, AI 智能搜…

    2026年10月30日 • 用户投稿
    100
  • Java如何创建一个学生选课管理系统

    Java如何创建一个学生选课管理系统Java如何创建一个学生选课管理系统Java如何创建一个学生选课管理系统Java如何创建一个学生选课管理系统

    答案:系统包含学生、课程和选课三大模块,通过Student、Course和CourseSelectionSystem类实现添加信息、选课、查看选课情况等功能,支持防止重复选课和课程人数限制,并可扩展至数据库存储与图形界面。 要创建一个学生选课管理系统,Java 是一个非常合适的选择。这个系统可以包含…

    2026年10月30日 • 用户投稿
    000
  • 优酷APP打不开是什么问题_优酷无法启动原因与修复方法

    优酷APP打不开是什么问题_优酷无法启动原因与修复方法优酷APP打不开是什么问题_优酷无法启动原因与修复方法优酷APP打不开是什么问题_优酷无法启动原因与修复方法优酷APP打不开是什么问题_优酷无法启动原因与修复方法

    优酷APP无法启动或闪退可能由软件冲突、缓存异常或权限限制引起。首先清除缓存与数据并尝试触发内置诊断工具修复;其次检查网络连接,关闭高带宽占用应用,切换网络环境;接着确认系统防火墙或安全软件未阻止优酷联网,将其加入白名单;最后卸载后从官方应用商店重新安装最新版本,确保权限授权完整,以恢复正常运行。 …

    2026年10月30日 • 用户投稿
    100
  • 谷歌浏览器无法同步书签是什么原因_谷歌浏览器书签同步失败解决方案

    谷歌浏览器无法同步书签是什么原因_谷歌浏览器书签同步失败解决方案谷歌浏览器无法同步书签是什么原因_谷歌浏览器书签同步失败解决方案谷歌浏览器无法同步书签是什么原因_谷歌浏览器书签同步失败解决方案谷歌浏览器无法同步书签是什么原因_谷歌浏览器书签同步失败解决方案

    首先确认谷歌账户登录状态及同步开关是否开启,检查书签同步选项是否启用,清除浏览器缓存与Cookie,重置同步服务以重建连接,关闭退出时清除数据的隐私设置,并可借助Floccus等第三方工具通过WebDAV实现替代同步。 如果您在使用谷歌浏览器时,发现书签未能在不同设备间更新,这通常是因为同步服务未能…

    2026年10月30日 • 用户投稿
    400
  • 2345看图王如何查看图片信息_2345看图王图片信息的查询方法

    2345看图王如何查看图片信息_2345看图王图片信息的查询方法2345看图王如何查看图片信息_2345看图王图片信息的查询方法2345看图王如何查看图片信息_2345看图王图片信息的查询方法2345看图王如何查看图片信息_2345看图王图片信息的查询方法

    打开2345看图王并双击图片,点击右下角“更多”按钮选择“图片信息”,在“常规”选项卡中查看文件名、大小、分辨率等基本信息;02. 切换至“EXIF”选项卡可查看相机型号、拍摄时间、焦距、光圈、快门速度等拍摄参数;03. 也可直接右键点击图片预览区域,选择“图片信息”快速访问上述内容。 如果您在使用…

    2026年10月30日 • 用户投稿
    000
  • 打开QQ邮箱 邮箱网页版官方登录在线入口

    打开QQ邮箱 邮箱网页版官方登录在线入口打开QQ邮箱 邮箱网页版官方登录在线入口打开QQ邮箱 邮箱网页版官方登录在线入口打开QQ邮箱 邮箱网页版官方登录在线入口

    QQ邮箱网页版官方登录入口为https://mail.qq.com。通过浏览器访问该网址可直达登录页面,支持账号密码输入及微信、QQ扫码登录,操作便捷且安全高效。页面简洁清晰,新用户易上手,并支持记住账号功能。与QQ好友体系深度整合,联系人同步,文件可一键转发为附件,未读邮件支持QQ消息提醒,实现跨…

    2026年10月30日 • 用户投稿
    000
  • 基于PP-PicoDet的【PP吸烟视频分析预警系统】

    基于PP-PicoDet的【PP吸烟视频分析预警系统】基于PP-PicoDet的【PP吸烟视频分析预警系统】基于PP-PicoDet的【PP吸烟视频分析预警系统】基于PP-PicoDet的【PP吸烟视频分析预警系统】

    PP吸烟视频分析预警检测系统基于PP-PicoDet模型,可检测禁烟场所吸烟行为并报警,应用场景广泛。其数据处理含解压缩、划分数据集等,环境需特定版本PaddlePaddle等。通过修改配置文件训练模型,经评估、预测后导出,还可转换为Paddle Lite模型部署于Android,mAP达85.92…

    2026年10月30日 • 用户投稿
    100
  • 微软CEO再发表暴论:游戏业界最好的创新就是赚钱!

    微软CEO再发表暴论:游戏业界最好的创新就是赚钱!微软CEO再发表暴论:游戏业界最好的创新就是赚钱!微软CEO再发表暴论:游戏业界最好的创新就是赚钱!微软CEO再发表暴论:游戏业界最好的创新就是赚钱!

    近日,外媒PC Gamer援引彭博社关于微软游戏部门利润预期的报道指出,在相关舆论发酵后,微软CEO萨提亚·纳德拉(Satya Nadella)于本周二出席GitHub大会期间接受了采访,就公司在游戏和技术领域的未来布局发表了看法。他表示,整个行业必须在生产流程、内容创作、发行机制以及经济模型等方面…

    2026年10月30日 • 用户投稿
    100
  • 在Java中如何通过Map计算键值对总数

    在Java中如何通过Map计算键值对总数在Java中如何通过Map计算键值对总数在Java中如何通过Map计算键值对总数在Java中如何通过Map计算键值对总数

    使用size()方法可获取Map中键值对总数,返回int值。示例中map.size()输出3;空Map返回0,重复put不增加size,clear()后size为0,remove()会减少size;常用于判空或统计。 在Java中,获取Map中键值对的总数非常简单,直接使用Map接口提供的size(…

    2026年10月30日 • 用户投稿
    1000
  • Linux用户usermod命令应用实例

    usermod命令用于修改Linux用户属性,如登录名(-l)、家目录(-d配合-m迁移)、Shell(-s)、UID(-u需手动更新文件属主)、主组(-g)和附加组(-G或-aG),还可锁定(-L)与解锁(-U)账户,是高效管理用户的重要工具。 usermod 命令用于修改 Linux 系统中已存…

    2026年10月30日
    300
  • 在Java中如何使用List.subList截取集合片段

    在Java中如何使用List.subList截取集合片段在Java中如何使用List.subList截取集合片段在Java中如何使用List.subList截取集合片段在Java中如何使用List.subList截取集合片段

    subList返回原列表的视图,修改子列表会影响原列表,且原列表结构变化后操作子列表会抛ConcurrentModificationException,如需独立副本应使用new ArrayList(subList())。 在Java中,List.subList 方法可以用来获取集合的一个视图片段,而…

    2026年10月30日 • 用户投稿
    000

发表回复

登录后才能评论
关注微信