不可变集合类型转换异常

article/2025/9/8 19:01:37

记录一个异常: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.hkcw.cn/article/yxOIOwAmVL.shtml

相关文章

初学python的我开始Leetcode题10-1

提示&#xff1a;100道LeetCode热题10-1主要是回溯相关&#xff0c;包括四题&#xff1a;全排列、子集、电话号码的字母组合、组合总和。由于初学&#xff0c;所以我的代码部分仅供参考。 前言 下周是第十六周&#xff0c;然后是两周的期末周&#xff0c;所以马上会缺两周左右…

IPTV电视直播 1.6.0 | 手机电视直播 秒播无卡顿

电视直播是一款功能强大且用户体验优秀的电视直播软件。它提供了丰富的节目资源&#xff0c;并支持高清画质播放&#xff0c;无论是家庭娱乐、移动办公还是学习&#xff0c;都能满足用户的需求。该应用完全无广告、无弹窗&#xff0c;确保用户享受纯净的观看体验。此外&#xf…

BugKu Web渗透之备份是个好习惯

启动场景后&#xff0c;网页显示一段字符串。 看起来像md5值&#xff0c;但是又过长了。 步骤一&#xff1a;右键查看源代码&#xff0c;没有发现任何异常。 步骤二&#xff1a;使用dirsearch去查看是否有其他可疑文件。 在终端输入&#xff1a; dirsearch -u http://117.72.…

深入理解 SELinux:通过 Nginx 和 SSH 服务配置实践安全上下文与端口策略

目录 一、引言 二、实验环境说明 三、实验 1&#xff1a;Nginx 服务安全上下文配置 3.1 实验目标 3.2 操作步骤 1. 开启 SELinux 并重启系统 2. 安装 Nginx 并创建自定义目录 3. 配置 Nginx 指向自定义目录 4. 分析 SELinux 上下文冲突 5. 修改上下文为合法类型 6. 验…

Linux 开发工具

1.sudo白名单 我们如果要让普通用户有sudo的权限 我们就要登录root用户 在/etc/sudoers目录下 通过文本编辑器&#xff08;我用的是vim&#xff09; 将要添加的用户 直接添加进去 如下图光标行就是我添加的白名单用户 然后我们添加的这个ly_centos就有sudo的权限了 2.gcc…

React 第四十九节 Router中useNavigation的具体使用详解及注意事项

前言 useNavigation 是 React Router 中一个强大的钩子&#xff0c;用于获取当前页面导航的状态信息。 它可以帮助开发者根据导航状态优化用户体验&#xff0c;如显示加载指示器、防止重复提交等。 一、useNavigation核心用途 检测导航状态&#xff1a;判断当前是否正在进行…

从数据持久化到网络通信与OpenCV:Qt应用程序开发的深度探索与实战

文章目录 前言一、QSettings&#xff1a;轻量级数据持久化方案1.1 QSettings 主要特点1.2 QSettings 常用函数整理 二、数据库2.1 连接SQLite数据库2.2 建表2.3 增删改 三、网络编程3.1 网络分层3.2 IP地址3.3 端口号3.4 基于TCP的Socket通信3.4 相关接口3.4.1核心类3.4.2 通信…

【产品经理从0到1】自媒体端产品设计

后台的定义 “后台” 与“前台”都是相对独立的平台&#xff0c;前台是服务于互联网用户的平台 &#xff0c;后台主要是支撑前台页面内容、数据及对前台业务情况的统计分析的系统&#xff1b; 后台与前台的区别 第1&#xff1a;使用用户不同 前台用户&#xff1a;互联网用户…

Ubuntu20.04操作系统ssh开启oot账户登录

文章目录 1 前提2 设置root密码3 允许ssh登录root账户3.1 编辑配置文件3.2 重启ssh服务 4 安全注意事项 1 前提 ssh可以使用普通用户正常登录。 2 设置root密码 打开终端&#xff0c;设置密码 sudo passwd root # 设置root密码3 允许ssh登录root账户 3.1 编辑配置文件 su…

四叉树实现四边形网格

import matplotlib.pyplot as plt import matplotlib.patches as patches import numpy as np # 四叉树节点 class QuadNode:def __init__(self, x, y, width, height, depth):self.x xself.y yself.width widthself.height heightself.depth depthself.children []self.…

园区智能化集成平台汇报方案

该方案为园区智能化集成平台设计,依据《智能建筑设计标准》等 20 余项国家与行业规范,针对传统园区信息孤岛、反应滞后、经验流失、管理粗放等痛点,构建可视化智慧园区管理平台,实现大屏数据可视化、三维设备监控、智慧运维(含工单管理、巡检打卡)、能源能耗分析、AI 安防…

C#中的BeginInvoke和EndInvoke:异步编程的双剑客

文章目录 引言1. BeginInvoke和EndInvoke的基本概念1.1 什么是BeginInvoke和EndInvoke1.2 重要概念解释 2. 委托中的BeginInvoke和EndInvoke2.1 BeginInvoke方法2.2 EndInvoke方法2.3 两者的关系 3. 使用方式与模式3.1 等待模式3.2 轮询模式3.3 等待句柄模式3.4 回调模式 4. 底…

基于通义千问的儿童陪伴学习和成长的智能应用架构。

1.整体架构概览 我们的儿童聊天助手将采用典型的语音交互系统架构,结合大模型能力和外部知识库: 2. 技术方案分解 2.1. 前端应用/设备 选择: 移动App(iOS/Android)、Web应用,或者集成到智能音箱/平板等硬件设备中。技术栈: 移动App: React Native / Flutter (跨平台…

【STIP】安全Transformer推理协议

Secure Transformer Inference Protocol 论文地址&#xff1a;https://arxiv.org/abs/2312.00025 摘要 模型参数和用户数据的安全性对于基于 Transformer 的服务&#xff08;例如 ChatGPT&#xff09;至关重要。虽然最近在安全两方协议方面取得的进步成功地解决了服务 Transf…

MyBatisPlus(1):快速入门

我们知道&#xff0c;MyBatis是一个优秀的操作数据库的持久层框架&#xff08;优秀持久层框架——MyBatis&#xff09;&#xff0c;其基于底层的JDBC进行高度封装&#xff0c;极大的简化了开发。但是对于单表操作而言&#xff0c;我们需要重复地编写简单的CRUD语句。这其实是不…

【ARM】【FPGA】【硬件开发】Chapter.1 AXI4总线协议

Chapter.1 AXI4总线协议 作者&#xff1a;齐花Guyc(CAUC) 一、总线介绍 AXI4总线 AXI4总线就像是SoC内部的“高速公路”&#xff0c;负责在不同硬件模块之间高效传输数据。 AXI4协议通过 5个独立通道 传输数据和控制信号&#xff0c;每个通道都有自己的信号线&#xff0c;互…

.NET 7 AOT 使用及 .NET 与 Go 语言互操作详解

.NET 7 AOT 使用及 .NET 与 Go 语言互操作详解 目录 .NET 7 AOT 使用及 .NET 与 Go 语言互操作详解 一、背景与技术概述 1.1 AOT 编译技术简介 1.2 Go 语言与 .NET 的互补性 二、.NET 7 AOT 编译实践 2.1 环境准备 2.2 创建 AOT 项目 2.3 AOT 编译流程 2.4 调试信息处…

Shortest path 代码

Project https://graphics.cs.utah.edu/research/projects/shortest-path-to-boundary/ Build and Debug Fork:(在Win10上&#xff09; https://github.com/chunleili/Shortest-Path-to-Boundary-for-Self-Intersecting-Meshes commit hash d3160168d2b6a58188d12e6cd959da…

Spring框架学习day1--基础概念

Spring基础部分**轻量级的**IOC&#xff1a;控制反转&#xff08;对象由自己管理变成交给框架管理&#xff09;AOP&#xff1a;面向切面编程一站式BaenSpring体系结构 Spring Hello World 搭建 Spring基础部分 Spring是一个轻量级的IOC、AOP的一站式java开发框架&#xff0c;为…

立志成为一名优秀测试开发工程师(第九天)——使用fiddler工具、request库进行接口测试

接口测试学习 目录 一、接口测试的介绍 二、抓包软件Fiddler的使用 三、使用Python的Request库发送get、post请求&#xff1a; 1.get请求 2.post请求 四、总结 登录接口实现 认证请求处理 异常处理 高级配置 接口测试工具类封装 测试用例设计规范 Cookie处理方案 …