当前位置: 首页 > news >正文

Java不可变集合详解

什么是不可变集合

不可变集合,英文叫 immutable

顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供,并且在整个生命周期中都不可改变。

为什么要使用不可变集合

不可变对象有很多优点,包括:

  • 当对象被不可信的库调用时,不可变形式是安全的
  • 不可变对象被多个线程调用时,不存在竞态条件问题
  • 不可变集合不需要考虑变化,因此可以节省时间和空间。所有不可变的集合都比它们的可变形式有更好的内存利用率(分析和测试细节)
  • 不可变对象因为有固定不变,可以作为常量来安全使用

创建对象的不可变拷贝是一项很好的防御性编程技巧。Guava为所有JDK标准集合类型和Guava新集合类型都提供了简单易用的不可变版本。

Java 9 版本以前, Collections提供了一组方法把可变集合封装成不可变集合,假如要创建一个包含 几个元素的 Set 集合,程序需要先创建 Set 集合,然后调用 几次 add() 方法向 Set 集合中添加元素。例如:

List<String> list = new ArrayList<String>();list.add("a");list.add("b");list.add("c");List<String> unmodifiableList = Collections.unmodifiableList(list);list.add("d");System.out.println(unmodifiableList);

输出的结果: [a,b,c,d] 

得出结论:Collections.unmodifiableList 实现的不是真正的不可变集合,当原始集合修改后,不可变集合也发生变化。

  • 笨重而且累赘:不能舒适地用在所有想做防御性拷贝的场景;
  • 不安全:要保证没人通过原集合的引用进行修改,返回的集合才是事实上不可变的;
  • 低效:包装过的集合仍然保有可变集合的开销,比如并发修改的检查、散列表的额外空间,等等。

如果你没有修改某个集合的需求,或者希望某个集合保持不变时,把它防御性地拷贝到不可变集合是个很好的实践。

但是Java 9 出了些新的生成不可变集合的方法,程序直接调用 Set、List、Map 的 of() 方法即可创建包含 N 个元素的不可变集合,这样一行代码就可创建包含 N 个元素的集合。

不可变意味着程序不能向集合中添加元素,也不能从集合中删除元素。

如下程序示范了如何创建不可变集合。

public class Java9Collection {
public static void main(String[] args) {
// 创建包含4个元素的Set集合
Set set = Set.of("Java", "Kotlin", "Go", "Swift");
System.out.println(set);
// 不可变集合,下面代码导致运行时错误
// set.add("Ruby");
// 创建包含4个元素的List集合List list = List.of(34, -25, 67, 231);
System.out.println(list);
// 不可变集合,下面代码导致运行时错误
// list.remove(1);
// 创建包含3个key-value对的Map集合Map map = Map.of("语文", 89, "数学", 82, "英语", 92);
System.out.println(map);
// 不可变集合,下面代码导致运行时错误
// map.remove("语文");
// 使用Map.entry()方法显式构建key-value对Map map2 = Map.ofEntries(Map.entry("语文", 89), Map.entry("数学", 82), Map.entry("英语", 92));
System.out.println(map2);}
}

从上面代码可以看出 Set、List 比较简单,程序只要为它们的 of() 方法传入 N 个集合元素即可创建 Set、List 集合。

创建不可变的 Map 集合有两个方法。使用 of() 方法时只要依次传入多个 key-value 对即可;还可使用 ofEntries() 方法,该方法可接受多个 Entry 对象,因此程序显式使用 Map.entry() 方法来创建 Map.Entry 对象。 

相关文章:

Java不可变集合详解

什么是不可变集合 不可变集合&#xff0c;英文叫 immutable 顾名思义就是说集合是不可被修改的。集合的数据项是在创建的时候提供&#xff0c;并且在整个生命周期中都不可改变。 为什么要使用不可变集合 不可变对象有很多优点&#xff0c;包括&#xff1a; 当对象被不可信的…...

常见的JavaScript日常问题

在众多的编程语言中&#xff0c; JavaScript 给大部分的人的第一印象是人畜无害&#xff0c;看起来就简单的&#xff0c;对稍微有点儿开发经验的人来说&#xff0c;在网页中写个JavaScript功能也相当简单。但是当你真的得了解了JavaScript之后就会发现&#xff0c;它比我们想象…...

css modules的用法和在react项目中的应用

参考文章 CSS Modules 的用法 CSS Modules 的功能很单纯&#xff0c;只加入了局部作用域和模块依赖&#xff0c;可以保证某个组件的样式&#xff0c;不会影响到其他组件。 局部作用域 CSS的规则都是全局的&#xff0c;任何一个组件的样式规则&#xff0c;都对整个页面有效。…...

【LangChain概念】了解语言链️:第2部分

一、说明 在LangChain的帮助下创建LLM应用程序可以帮助我们轻松地链接所有内容。LangChain 是一个创新的框架&#xff0c;它正在彻底改变我们开发由语言模型驱动的应用程序的方式。通过结合先进的原则&#xff0c;LangChain正在重新定义通过传统API可以实现的极限。 在上一篇博…...

步入React前厅 - Css In React

目录 扩展学习资料 行内样式 引入样式表 CSS Module /src/components/common.module.css /src/components/listitem.module.css css管理进阶 Css管理工具 练习 扩展学习资料 资料名称 链接 css module CSS Modules 用法教程 - 阮一峰的网络日志 在React中使…...

OpenCV(三)——图像分割(二)

目录 4.边缘检测 4.1 图像梯度的概念 4.2 模板卷积和梯度图的概念 4.3 梯度算子...

28.Netty源码之缓存一致性协议

Mpsc Queue 基础知识 Mpsc 的全称是 Multi Producer Single Consumer&#xff0c;多生产者单消费者。Mpsc Queue 可以保证多个生产者同时访问队列是线程安全的&#xff0c;而且同一时刻只允许一个消费者从队列中读取数据。 Netty Reactor 线程中任务队列 taskQueue 必须满足多个…...

造个轮子-任务调度执行小框架-任务清单执行恢复实现

文章目录 前言恢复执行流程失败任务执行重启执行中任务恢复执行修复组件整合组件整合容器启动类总结前言 okey,通过前面的两篇文章,关于这个任务执行这一块,我想应该是明白了。但是这里的话,还是不够的。我们希望对于任务还可以做到执行失败的重试执行,关于这个意外宕机的…...

若依部署前后端

打包项目 前端打包 npm run build:prod将代码上传到指定目录 配置nginx转发 server{listen 8090;server_name localhost;location / {root /home/cc_library/dist;index index.html index.htm;# 配置 history模式&#xff0c;刷新页面会404&#xff0c;&#xff0c;因为服…...

2009年上半年 软件设计师 下午试卷

博主介绍&#xff1a;✌全网粉丝3W&#xff0c;全栈开发工程师&#xff0c;从事多年软件开发&#xff0c;在大厂呆过。持有软件中级、六级等证书。可提供微服务项目搭建与毕业项目实战&#xff0c;博主也曾写过优秀论文&#xff0c;查重率极低&#xff0c;在这方面有丰富的经验…...

SpringBoot使用自定义事件监听器的demo

记录一下SpringBoot自定义事件监听器的使用方法 案例源码:SpringBoot使用自定义事件监听器的demo 使用的SpringBoot2.0.x版本 <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><…...

arcgis定义投影与投影

1、定义 地理坐标系&#xff08;GCS&#xff09;&#xff1a;利用地球表面的经纬度表示的坐标系统。一般单位为度。投影坐标系&#xff08;PCS&#xff09;&#xff1a;利用数学换算将三维地球表面上的经纬度坐标转换到二维平面上的坐标系统。一般单位为米。可以认为&#xff…...

Flink多流处理之Broadcast(广播变量)

写过Spark批处理的应该都知道,有一个广播变量broadcast这样的一个算子,可以优化我们计算的过程,有效的提高效率;同样在Flink中也有broadcast,简单来说和Spark中的类似,但是有所区别,首先Spark中的broadcast是静态的数据,而Flink中的broadcast是动态的,也就是源源不断的数据流.在…...

LVS/DR+Keepalived负载均衡实战(一)

引言 负载均衡这个概念对于一个IT老鸟来说再也熟悉不过了&#xff0c;当听到此概念的第一反应是想到举世闻名的nginx&#xff0c;但殊不知还有一个大名鼎鼎的负载均衡方案可能被忽略了&#xff0c;因为对于一般系统来说&#xff0c;很多应用场合中采用nginx基本已经满足需求&a…...

测试DWPose的onnx +Unity barracuda

环境&#xff1a; Unity Barracuda 3.0.1 从github直接拉取的barracuda仓库才能装到这个版本Barracuda以后不再升级了&#xff0c;会迁移到Unity AI大计划里的Sentis 我想申请的来着但好像已经不开放了 Unity 2021.3.20模型&#xff1a;dw-ll_ucoco_384.onnx 报了一些错&…...

轻装上阵,不调用jar包,用C#写SM4加密算法【卸载IKVM 】

前言 记得之前写了一个文章&#xff0c;是关于java和c#加密不一致导致需要使用ikvm的方式来进行数据加密&#xff0c;主要是ikvm把打包后的jar包打成dll包&#xff0c;然后Nuget引入ikvm&#xff0c;从而实现算法的统一&#xff0c;这几天闲来无事&#xff0c;网上找了一下加密…...

redis学习笔记(一)

文章目录 一、引言二、redis介绍2.1、定义2.2、Redis的数据类型及主要特性2.3、Redis的应用场景有哪些&#xff1f; 三、redis环境安装3.1、下载和安装 一、引言 在Web应用发展的初期&#xff0c;那时关系型数据库受到了较为广泛的关注和应用&#xff0c;原因是因为那时候Web站…...

最优化问题 - 拉格朗日对偶

primal 原问题 dual 对偶问题 目标函数 约束条件 可行域D 对偶专题 “拉格朗日对偶问题”如何直观理解&#xff1f;“KKT条件” “Slater条件” “凸优化”打包理解——bilibili 王木头 拉格朗日乘子法与对偶问题...

关于ISO27701隐私信息安全管理体系介绍

01 什么是ISO27701 ISO27701是对ISO27001信息安全管理和ISO27002安全控制的隐私扩展&#xff0c;全称《安全技术—扩展ISO27001和ISO27002的隐私信息管理—要求与指南》&#xff0c;是ISO标准委员会以ISO 27001为基准&#xff0c;以ISO27552为蓝本&#xff0c;建立发布的隐私…...

C语言案例 分数列求和-11

题目&#xff1a;有一分数列&#xff1a;2 / 1,3 / 2,5 / 3,8 / 5,13 / 8,21 / 13 …求出这个数列的前20项之和。 程序分析 这是一个典型的分数列数学逻辑题&#xff0c;考究这类题目是需要从已知的条件中找到它们的分布规律 我们把前6荐的分子与分母分别排列出来&#xff0c;…...

[实战] 制造业数字化:GDT 形位公差识别与自动化检验计划生成指南

在精密制造与质量控制领域&#xff0c;GD&T 形位公差识别&#xff08;GD&T recognition&#xff09;一直是连接设计研发与质量检验的“最后一公里”。随着工业4.0的深入&#xff0c;如何高效处理工程图纸中的几何公差&#xff0c;已成为企业提升 FAI&#xff08;首件检…...

Sun-Panel:打造你的专属NAS门户,从零开始构建高效导航首页

1. 为什么你需要一个NAS导航首页&#xff1f; 每天打开电脑&#xff0c;第一件事就是面对浏览器里密密麻麻的书签栏——Jellyfin、Nextcloud、Bitwarden、Transmission...这些自建服务分散在不同的IP和端口上&#xff0c;记不住地址就得反复翻找记事本。更头疼的是&#xff0c;…...

如何用Idle Master实现Steam卡片自动化收集:终极完整指南

如何用Idle Master实现Steam卡片自动化收集&#xff1a;终极完整指南 【免费下载链接】idle_master Get your Steam Trading Cards the Easy Way 项目地址: https://gitcode.com/gh_mirrors/id/idle_master 还在为收集Steam交易卡片而烦恼吗&#xff1f;每天手动切换游戏…...

Python系列AI系列(仅供参考-推荐):AI Coding 进阶指南:Trae AI插件在Pycharm中的高效配置与实战技巧

AI Coding 进阶指南&#xff1a;Trae AI插件在Pycharm中的高效配置与实战技巧AI Coding 进阶指南&#xff1a;Trae AI插件在Pycharm中的高效配置与实战技巧1. 为什么开发者需要Trae AI插件2. 安装与基础配置详解2.1 插件安装的正确姿势2.2 账号配置与模型选择3. 日常开发中的高…...

现代C内存安全编码规范2026(GCC 14/Clang 18原生支持清单首次公开)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;现代C内存安全编码规范2026概述 C语言因其零成本抽象与硬件贴近性仍在嵌入式系统、操作系统内核及高性能服务中占据核心地位。然而&#xff0c;传统C标准&#xff08;如C11/C17&#xff09;对内存安全缺…...

阶跃 StepAudio 2.5 ASR 上线!500TPS 极速推理,30分钟语音“秒级转写”

语音 Agent 首字响应慢&#xff0c;很多人以为是 LLM 的锅。其实真正的延时瓶颈常在 ASR&#xff08;自动语音识别&#xff09;&#xff1a;传统的逐 token 串行输出——一段 5 分钟音频&#xff0c;要等几十秒才能拿到完整转写结果&#xff0c;整条链路卡在这一步。 StepAudi…...

BilibiliDown:跨平台B站视频下载的完整解决方案

BilibiliDown&#xff1a;跨平台B站视频下载的完整解决方案 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader &#x1f633; 项目地址: https://gitcode.com/gh_mirrors/bi/Bili…...

3分钟搭建你的专属手绘白板:Excalidraw完全入门指南

3分钟搭建你的专属手绘白板&#xff1a;Excalidraw完全入门指南 【免费下载链接】excalidraw Virtual whiteboard for sketching hand-drawn like diagrams 项目地址: https://gitcode.com/GitHub_Trending/ex/excalidraw 你是否曾在会议中需要快速绘制流程图&#xff0…...

瑞芯微RK3588 C++实战:Yolov8检测与分割模型端到端部署指南

1. 环境准备与工具链配置 在RK3588上部署Yolov8模型前&#xff0c;需要搭建完整的开发环境。我推荐使用Ubuntu 20.04作为基础系统&#xff0c;这个版本对RKNN-Toolkit2的支持最为稳定。首先需要安装以下核心组件&#xff1a; RKNN-Toolkit2-1.5.2&#xff1a;这是瑞芯微官方提供…...

Origin数据处理别再手动算!手把手教你用F(x)栏和公式编辑栏搞定复杂计算

Origin数据处理革命&#xff1a;用F(x)栏和公式编辑栏实现高效自动化计算 第一次接触Origin的数据处理功能时&#xff0c;我还在实验室里手动计算上百组实验数据。直到发现F(x)栏和公式编辑栏的组合用法&#xff0c;才意识到自己浪费了多少时间在重复劳动上。本文将带你彻底告别…...