不可变集合类型转换异常

记录一个异常:class java.util.ImmutableCollections$ListN cannot be cast to class java.util.ArrayList (java.util.ImmutableCollections$ListN and java.util.ArrayList

文章目录

  • 1、原因
  • 2、解决方式一
  • 3、解决方式二
  • 4、关于不可变集合的补充
    • 4.1 JDK8和9的对比
    • 4.2 相关源码
    • 4.3 不可变集合的使用场景

1、原因

代码中做了类型转换,将一个不可变集合 (ImmutableCollections$ListN) 强制转换为 可变集合 (ArrayList)

List<String> immutableList = List.of("A", "B", "C"); // Java 9+ 不可变列表
ArrayList<String> mutableList = (ArrayList<String>) immutableList; // ❌ 抛出 ClassCastException

业务相关错误代码:

 List<ClusterJob> jobs = result.get().getJobs().stream().sorted(Comparator.comparing(ClusterJob::getOrderUpdateTime).reversed()).toList();
ClusterJobResponse response = new ClusterJobResponse();
response.setJobs((ArrayList<ClusterJob>) jobs);
return BaseVo.createSuccessWithData(response);

而toList方法的源码,是一个不可变集合:

default List<T> toList() {return (List<T>) Collections.unmodifiableList(new ArrayList<>(Arrays.asList(this.toArray())));}

2、解决方式一

使用 new ArrayList<>(Collection) 复制

List<String> immutableList = List.of("A", "B", "C");
ArrayList<String> mutableList = new ArrayList<>(immutableList); // ✅ 复制数据

3、解决方式二

直接使用传统的Collectors.toList()

List<ClusterJob> jobs = result.get().getJobs().stream().sorted(Comparator.comparing(ClusterJob::getOrderUpdateTime).reversed()).collect(Collectors.toList());
ClusterJobResponse response = new ClusterJobResponse();
response.setJobs((ArrayList<ClusterJob>) jobs);

4、关于不可变集合的补充

4.1 JDK8和9的对比

不可变集合(Immutable Collections)是指创建后内容不可修改的集合,任何尝试修改(add、remove、set)的操作都会抛出 UnsupportedOperationException

  • Java 8 及之前:使用 Collections.unmodifiableXXX() 做一个包装(只是视图,底层数据仍可能被修改)
  • Java 9+:新增 List.of(), Set.of(), Map.of() 等工厂方法(真正的不可变集合)
public class Main {public static void main(String[] args) {List<String> original = new ArrayList<>();original.add("A");original.add("B");List<String> unmodifiable = Collections.unmodifiableList(original);// 成功original.add("C");// UnsupportedOperationExceptionunmodifiable.add("C");}
}

如上,使用Collections.unmodifiableList包装后得到的集合,其不可被更新,但原始被包装的集合,还是可以更改

在这里插入图片描述
Java9+以后,创建不可变集合:

List<String> immutableList = List.of("A", "B", "C");  
Set<Integer> immutableSet = Set.of(1, 2, 3);  
Map<String, Integer> immutableMap = Map.of("A", 1, "B", 2);  // 空集合
List<String> emptyList = List.of();  
Map<String, Integer> emptyMap = Map.of();  

此时的集合,不可被更新,自然也不能被类型转换,如 (ArrayList) List.of(...) 会抛异常,推荐使用这种方式,内存占用更小,性能更好

4.2 相关源码

核心类:ImmutableCollections
在这里插入图片描述

throw UnsupportedOperationException在日常开发用的也很多,一个接口,不同的策略,有时候某一个实现类并不需要实现接口的某一个方法,此时可以直接抛这个异常

4.3 不可变集合的使用场景

用于定义一些存放固定值的常量或者成员变量:

public static final List<String> COUNTRIES = List.of("China", "US", "UK");
private static final Map<String, Integer> CACHE = Map.of("VIP", 100,"NORMAL", 10
);

用于防御性拷贝,List.copyOf创建不可变副本,此时,哪怕后面original被改变了,我自己还是不受影响

public void processData(List<String> original) {List<String> safeCopy = List.copyOf(original); // 创建不可变副本// 安全使用 safeCopy
}

当然,以下这个写法也行

List<String> original = new ArrayList<>();
List<String> listNew = new ArrayList<>(original);

new ArrayList<>(original)List.copyOf(original) 都会创建独立副本,后续对 original 的修改不会影响副本,区别是:前者返回的一个可变集合,后者则是一个严格的不可变集合

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/news/907904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【DAY37】早停策略和模型权重的保存

内容来自浙大疏锦行python打卡训练营 浙大疏锦行 知识点&#xff1a; 过拟合的判断&#xff1a;测试集和训练集同步打印指标模型的保存和加载 仅保存权重保存权重和模型保存全部信息checkpoint&#xff0c;还包含训练状态 早停策略 作业&#xff1a; 对信贷数据集训练后保存权…

【Zephyr 系列 3】多线程与调度机制:让你的 MCU 同时干多件事

好的,下面是Zephyr 系列第 3 篇:聚焦 多线程与调度机制的实践应用,继续面向你这样的 Ubuntu + 真板实战开发者,代码清晰、讲解通俗、结构规范,符合 CSDN 高质量博客标准。 🧠关键词:Zephyr、线程调度、k_thread、k_sleep、RTOS、BluePill 📌适合人群:想从裸机开发进…

实现RabbitMQ多节点集群搭建

目录 引言 一、环境准备 二、利用虚拟机搭建 ​ 三、镜像集群配置 四、HAProxy实现负载均衡(主用虚拟机操作) 五、测试RabbitMQ集群搭建情况 引言 在现代分布式系统中&#xff0c;消息队列&#xff08;Message Queue&#xff09;扮演着至关重要的角色,而 RabbitMQ 作为…

异步上传石墨文件进度条前端展示记录(采用Redis中String数据结构实现-苏东坡版本)

昔者&#xff0c;有客临门&#xff0c;亟需自石墨文库中撷取卷帙若干。此等文册&#xff0c;非止一卷&#xff0c;乃累牍连篇&#xff0c;亟需批量转置。然吾辈虑及用户体验&#xff0c;当效东坡"腹有诗书气自华"之雅意&#xff0c;使操作如行云流水&#xff0c;遂定…

Axure 基础入门

目录 认识产品经理 项目团队* 基本概述 认识产品经理 A公司产品经理 B公司产品经理 C公司产品经理 D公司产品经理 产品经理工作范围 产品经理工作流程* 产品经理的职责 产品经理的分类 产品经理能力要求 产品工具 产品体验报告 原型设计介绍 原型设计概述 为…

零基础学习计算机网络编程----socket实现UDP协议

本章将会详细的介绍如何使用 socket 实现 UDP 协议的传送数据。有了前面基础知识的铺垫。对于本章的理解将会变得简单。将会从基础的 Serve 的初始化&#xff0c;进阶到 Client 的初始化&#xff0c;以及 run。最后实现一个简陋的小型的网络聊天室。 目录 1.UdpSever.h 1.1 构造…

普中STM32F103ZET6开发攻略(二)

接上文&#xff1a;普中STM32F103ZET6开发攻略&#xff08;一&#xff09;-CSDN博客 各位看官老爷们&#xff0c;点击关注不迷路哟。你的点赞、收藏&#xff0c;一键三连&#xff0c;是我持续更新的动力哟&#xff01;&#xff01;&#xff01; 目录 接上文&#xff1a;普中…

用提示词写程序(3),VSCODE+Claude3.5+deepseek开发edge扩展插件V2

edge扩展插件;筛选书签,跳转搜索,设置背景 链接: https://pan.baidu.com/s/1nfnwQXCkePRnRh5ltFyfag?pwd86se 提取码: 86se 导入解压的扩展文件夹: 导入扩展成功: edge扩展插件;筛选书签,跳转搜索,设置背景

电脑桌面便签软件哪个好?桌面好用便签备忘录推荐

在日常办公中&#xff0c;一款优秀的桌面便签工具能显著提升工作效率。面对市面上琳琅满目的选择&#xff0c;不少用户都难以抉择。如果你正在寻找一款兼具轻量化与多功能性的便签软件&#xff0c;那么集实用性与便捷性于一身的"好用便签"&#xff0c;或许就是你的理…

性能优化 - 工具篇:基准测试 JMH

文章目录 Pre引言1. JMH 简介2. JMH 执行流程详解3. 关键注解详解3.1 Warmup3.2 Measurement3.3 BenchmarkMode3.4 OutputTimeUnit3.5 Fork3.6 Threads3.7 Group 与 GroupThreads3.8 State3.9 Setup 与 TearDown3.10 Param3.11 CompilerControl 4. 示例代码与分析4.1 关键点解读…

2025年十大AI幻灯片工具深度评测与推荐

我来告诉你一个好消息。 我们已经亲自测试和对比了市面上最优秀的AI幻灯片工具&#xff0c;让你无需再为选择而烦恼。 得益于AI技术的飞速发展&#xff0c;如今你可以快速制作出美观、专业的幻灯片。 这些智能平台的功能远不止于配色美化——它们能帮你头脑风暴、梳理思路、…

雪花算法:分布式ID生成的优雅解决方案

一、雪花算法的核心机制与设计思想 雪花算法&#xff08;Snowflake&#xff09;是由Twitter开源的分布式ID生成算法&#xff0c;它通过巧妙的位运算设计&#xff0c;能够在分布式系统中快速生成全局唯一且趋势递增的ID。 1. 基本结构 雪花算法生成的是一个64位&#xff08;lo…

第1章:走进Golang

第1章&#xff1a;走进Golang 一、Golang简介 Go语言&#xff08;又称Golang&#xff09;是由Google的Robert Griesemer、Rob Pike及Ken Thompson开发的一种开源编程语言。它诞生于2007年&#xff0c;2009年11月正式开源。Go语言的设计初衷是为了在不损失应用程序性能的情况下…

Higress项目解析(二):Proxy-Wasm Go SDK

3、Proxy-Wasm Go SDK Proxy-Wasm Go SDK 依赖于 tinygo&#xff0c;同时 Proxy - Wasm Go SDK 是基于 Proxy-Wasm ABI 规范使用 Go 编程语言扩展网络代理&#xff08;例如 Envoy&#xff09;的 SDK&#xff0c;而 Proxy-Wasm ABI 定义了网络代理和在网络代理内部运行的 Wasm …

NVMe IP现状扫盲

SSD优势 与机械硬盘&#xff08;Hard Disk Driver, HDD&#xff09;相比&#xff0c;基于Flash的SSD具有更快的数据随机访问速度、更快的传输速率和更低的功耗优势&#xff0c;已经被广泛应用于各种计算领域和存储系统。SSD最初遵循为HDD设计的现有主机接口协议&#xff0c;例…

`docker commit` 和 `docker save`区别

理解 docker commit 和 docker save 之间的区别对于正确管理 Docker 镜像非常重要。让我们详细解释一下这两个命令的作用及其区别。 1. docker commit 作用&#xff1a; docker commit roop-builder roop:v1 命令的作用是基于一个正在运行的容器 roop-builder 创建一个新的镜…

Linux内核体系结构简析

1.Linux内核 1.1 Linux内核的任务 从技术层面讲&#xff0c;内核是硬件和软件之间的一个中间层&#xff0c;作用是将应用层序的请求传递给硬件&#xff0c;并充当底层驱动程序&#xff0c;对系统中的各种设备和组件进行寻址。从应用程序的角度讲&#xff0c;应用程序与硬件没有…

python爬虫:Ruia的详细使用(一个基于asyncio和aiohttp的异步爬虫框架)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Ruia概述1.1 Ruia介绍1.2 Ruia特点1.3 安装Ruia1.4 使用案例二、基本使用2.1 Request 请求2.2 Response - 响应2.3 Item - 数据提取2.4 Field 提取数据2.5 Spider - 爬虫类2.6 Middleware - 中间件三、高级功能3.1 …

网络攻防技术二:密码学分析

文章目录 一、传统密码分析方法1、根据明文、密文等信息的掌握情况分类 2、从密码分析途径分类二、密码旁路分析1、概念2、旁路分析方法三、现代密码系统1、对称密码&#xff08;单密钥&#xff09;2、公开密码&#xff08;成对密钥&#xff09; 四、典型对称密码&#xff08;单…

Linux --TCP协议实现简单的网络通信(中英翻译)

一、什么是TCP协议 1.1 、TCP是传输层的协议&#xff0c;TCP需要连接&#xff0c;TCP是一种可靠性传输协议&#xff0c;TCP是面向字节流的传输协议&#xff1b; 二、TCPserver端的搭建 2.1、我们最终好实现的效果是 客户端在任何时候都能连接到服务端&#xff0c;然后向服务…