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

Arrays.asList()新增报错,该怎么解决

一、前言

在 Java 开发中,Arrays.asList() 是一个常用的工具方法,它允许开发者快速将数组转换为列表。尽管这个方法非常方便,但许多开发者在使用时可能会遭遇一个常见的错误:尝试向由 Arrays.asList() 返回的列表中添加元素时抛出异常。本文将详细探讨这个现象的根本原因,并提供相关的使用示例和解决方案。。

二、事故回顾

这个问题是出现开发一个电商平台的订单系统时,遇到了类似的问题。需要将一个订单ID数组转换为一个List,并在后续的业务逻辑中向这个List中添加新的订单ID。

由于小伙伴经验不足,使用了Arrays.asList()方法,部署到线上导致在添加新订单ID时抛出了UnsupportedOperationException异常,整个订单处理流程中断,线上系统出现了严重的故障。

影响分析

这次事故对电商平台造成了巨大的影响:

  1. 用户体验下降: 由于订单处理流程中断,用户无法正常下单,导致用户体验大幅下降。
  2. 业务中断: 订单系统的故障直接影响到了整个电商平台的业务运营,造成了大量的订单积压。
  3. 经济损失: 由于业务中断,平台失去了大量的潜在收入,给公司带来了不小的经济损失。
  4. 信任危机: 频繁的系统故障让用户对平台的信任度下降,可能导致用户流失。

后面也是及时修复,吸取本次事故教训。

三、事故问题描述

1、首先先简单描述一下这个事故问题,废话不多说,直接看实际业务代码,也就将一个数组转换为List,并对这个List进行增删操作。

Integer[] arr = {1, 2};List<Integer> list = Arrays.asList(arr);list.add(3);

上述代码看起来,没问题,编译器也没有报错。但是运行这段代码时,会抛出UnsupportedOperationException异常,提示我们不支持添加操作。这究竟是怎么回事呢?

所以这是不是个大坑,如果在实际开发中没有进行自测,必定不会酿成重大线上事故。

四、问题分析

上述已经知道这个使用Arrays.asList()将数组装换成List会在add情况会报错,接下来深入源码进行分析。

Arrays.asList()的内部实现

Arrays.asList(arr)方法实际上返回的是一个Arrays类的内部类ArrayList,而不是我们常用的java.util.ArrayList。这个内部类ArrayList继承自AbstractList,并没有实现add和remove方法。

Arrays类的内部类ArrayList完整源码如下:

private static class ArrayList<E> extends AbstractList<E>implements RandomAccess, java.io.Serializable
{private static final long serialVersionUID = -2764017481108945198L;private final E[] a;ArrayList(E[] array) {a = Objects.requireNonNull(array);}@Overridepublic int size() {return a.length;}@Overridepublic Object[] toArray() {return a.clone();}@Override@SuppressWarnings("unchecked")public <T> T[] toArray(T[] a) {int size = size();if (a.length < size)return Arrays.copyOf(this.a, size,(Class<? extends T[]>) a.getClass());System.arraycopy(this.a, 0, a, 0, size);if (a.length > size)a[size] = null;return a;}@Overridepublic E get(int index) {return a[index];}@Overridepublic E set(int index, E element) {E oldValue = a[index];a[index] = element;return oldValue;}@Overridepublic int indexOf(Object o) {E[] a = this.a;if (o == null) {for (int i = 0; i < a.length; i++)if (a[i] == null)return i;} else {for (int i = 0; i < a.length; i++)if (o.equals(a[i]))return i;}return -1;}@Overridepublic boolean contains(Object o) {return indexOf(o) != -1;}@Overridepublic Spliterator<E> spliterator() {return Spliterators.spliterator(a, Spliterator.ORDERED);}@Overridepublic void forEach(Consumer<? super E> action) {Objects.requireNonNull(action);for (E e : a) {action.accept(e);}}@Overridepublic void replaceAll(UnaryOperator<E> operator) {Objects.requireNonNull(operator);E[] a = this.a;for (int i = 0; i < a.length; i++) {a[i] = operator.apply(a[i]);}}@Overridepublic void sort(Comparator<? super E> c) {Arrays.sort(a, c);}
}

可以看到并没有实现add和remove方法,这两个方法在父类中,默认抛出UnsupportedOperationException异常。

具体原因

下面是内部源码的分析

1.内部类ArrayList的限制:

Arrays.asList(arr)返回的内部类ArrayList是一个固定长度的列表,它没有实现add和remove方法。

当我们调用list.add(3)时,实际上调用的是AbstractList中的add方法,而这个方法直接抛出了UnsupportedOperationException异常。

2.源码分析:

AbstractList的add方法如下:

五、解决方案

面对这一限制,开发者可以采取以下几种方式来处理 Arrays.asList() 返回的列表:

1、使用 new ArrayList<>() 创建可变列表

如果需要一个可变大小的列表,可以使用 new ArrayList<>(Arrays.asList(fruits)) 进行转换:   这种方式创建了一个新的 ArrayList 实例,它的大小是可变的,因此可以自由添加、删除元素。

List<String> dynamicList = new ArrayList<>(Arrays.asList("Apple", "Banana", "Cherry"));dynamicList.add("Date");  // 现在可以成功添加元素System.out.println(dynamicList);

2、直接初始化 ArrayList

另一种选择是直接使用 ArrayList 的构造函数,并传入数组元素:   这种方法提供了更大的灵活性,适合需要动态修改的场景。

List<String> dynamicList = new ArrayList<>();Collections.addAll(dynamicList, "Apple", "Banana", "Cherry");dynamicList.add("Date");  // 添加成功

3、使用流(Streams)

在 Java 8 及更高版本中,可以利用流的 API 来创建可变列表:   这种方法简洁而现代化,适合喜欢函数式编程风格的开发者。

List<String> dynamicList = Stream.of("Apple", "Banana", "Cherry").collect(Collectors.toList());dynamicList.add("Date");  // 添加成功

转载:小哈学Java

相关文章:

Arrays.asList()新增报错,该怎么解决

一、前言 在 Java 开发中&#xff0c;Arrays.asList() 是一个常用的工具方法&#xff0c;它允许开发者快速将数组转换为列表。尽管这个方法非常方便&#xff0c;但许多开发者在使用时可能会遭遇一个常见的错误&#xff1a;尝试向由 Arrays.asList() 返回的列表中添加元素时抛出…...

【热门主题】000072 分布式数据库:开启数据管理新纪元

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 【热…...

基于Springboot开发的云野旅游平台

一、功能介绍 云野旅游平台包含管理员、用户两个角色以及前后台系统。 前台系统功能 用户登录成功后&#xff0c;可以进行查看旅游路线、最新线路、旅游资讯、个人中心、后台管理、购物车、客服等功能模块。进行相对应操作。 后台系统功能 管理员或用户登录成功后&#xf…...

2024金盾信安杯线上赛 MISC ezpng[wp]

下载题目发现给了个password和png 图片发现损坏的 password丢随波逐流一键解 base64 给出解码的结果是 cimbar搜索发现在Github有工具 然后对附件中的图片进行小厨房xor 得到一张新图片 利用工具进行跑出答案...

搭建业务的性能优化指南

这是一篇搭建业务优化的心路历程&#xff0c;也是写给搭建业务的性能优化指南。 前言 直到今天&#xff0c;淘内的页面大多都迁移到了 SSR&#xff0c;从我们终端平台 - 搭建研发团队的视角看&#xff0c;业务大致可以分为两类 —— 搭建派 和 源码派。 这两者互不冲突&#xf…...

电脑提示报错“Directx error”怎么解决?是什么原因导致的?游戏软件提示“Directx error”错误的解决方案

DirectX Error&#xff08;DX错误&#xff09;通常指的是在使用基于DirectX技术的应用程序&#xff08;尤其是游戏&#xff09;时遇到的问题。这个问题可能由多种因素导致&#xff0c;以下是一些可能的原因及相应的解决方案&#xff1a; 可能的原因 DirectX版本不匹配&#x…...

Linux——自定义简单shell

shell 自定义shell目标普通命令和内建命令&#xff08;补充&#xff09; shell实现实现原理实现代码 自定义shell 目标 能处理普通命令能处理内建命令要能帮助我们理解内建命令/本地变量/环境变量这些概念理解shell的运行 普通命令和内建命令&#xff08;补充&#xff09; …...

基于matlab程序实现人脸识别

1.人脸识别流程 1.1.1基本原理 基于YCbCr颜色空间的肤色模型进行肤色分割。在YCbCr色彩空间内对肤色进行了建模发现&#xff0c;肤色聚类区域在Cb—Cr子平面上的投影将缩减&#xff0c;与中心区域显著不同。采用这种方法的图像分割已经能够较为精确的将人脸和非人脸分割开来。…...

Unity跨平台基本原理

Unity跨平台基本原理 Unity跨平台基本原理微软的.Net是什么微软做 .Net平台的目的如何实现的.Net跨语言&#xff1f;总结 .Net Framework.Net Framework的体系结构CLR总结 如何实现的跨平台&#xff1f;.Net Core.Net FrameWork 到 .Net CoreMonoMono如何实现跨平台总结如何实现…...

【前端开发】小程序无感登录验证

概述 封装的网络请求库&#xff0c;主要用于处理 API 请求并支持自动处理 token 过期 和 token 刷新&#xff0c;适用于需要身份验证的应用场景&#xff0c;特别是在移动端中。 主要功能 自动附加 Token 在每个请求中自动附加 Authorization 头部&#xff0c;使用存储的 acces…...

Flink常见面试题

1、Flink 的四大特征&#xff08;基石&#xff09; 2、Flink 中都有哪些 Source&#xff0c;哪些 Sink&#xff0c;哪些算子&#xff08;方法&#xff09; 预定义Source 基于本地集合的source&#xff08;Collection-based-source&#xff09; 基于文件的source&#xff08;…...

spark同步mysql数据到sqlserver

使用Apache Spark将数据从MySQL同步到SQL Server是一个常见的ETL&#xff08;Extract, Transform, Load&#xff09;任务。这里提供一个基本的步骤指南&#xff0c;以及一些代码示例来帮助你完成这项工作。 ### 前提条件 1. **安装Spark**&#xff1a;确保你的环境中已经安装了…...

Python Web 开发:FastAPI 基本概念与应用

Python Web 开发&#xff1a;FastAPI 基本概念与应用 目录 ✨ 1. FastAPI 路由&#xff08;定义请求路径&#xff09;&#x1f680; 2. HTTP 请求方法&#xff08;GET、POST、PUT、DELETE&#xff09;&#x1f511; 3. 参数类型&#xff08;路径参数、查询参数、请求体&#…...

Linux设置开启启动脚本

1.问题 每次启动虚拟机需要手动启动网络&#xff0c;不然没有enss33选项 需要启动 /mnt/hgfs/dft_shared/init_env/initaial_env.sh 文件 2.解决方案 2.1 修改/etc/rc.d/rc.local 文件 /etc/rc.d/rc.local 文件会在 Linux 系统各项服务都启动完毕之后再被运行。所以你想要…...

go并发设计模式runner模式

go并发设计模式runner模式 真正运行的程序不可能是单线程运行的&#xff0c;go语言中最值得骄傲的就是CSP模型了&#xff0c;可以说go语言是CSP模型的实现。 假设现在有一个程序需要实现&#xff0c;这个程序有以下要求&#xff1a; 程序可以在分配的时间内完成工作&#xff0…...

nn.RNN解析

以下是RNN的计算公式,t时刻的隐藏状态H(t)等于前一时刻隐藏状态H(t-1)乘以参数矩阵&#xff0c;再加t时刻的输入x(t)乘以参数矩阵&#xff0c;最后再通过激活函数&#xff0c;等到t时刻隐藏状态。 下图是输出input和初始化的隐藏状态&#xff0c;当参数batch_first True时候&…...

How to monitor Spring Boot apps with the AppDynamics Java Agent

本文介绍如何使用 AppDynamics Java 代理监视 Azure Spring Apps 中的 Spring Boot 应用程序。 使用 AppDynamics Java 代理可以&#xff1a; 监视应用程序使用环境变量配置 AppDynamics Java 代理 在 AppDynamics 仪表板中检查所有监视数据 How to monitor Spring Boot app…...

Linux学习笔记12 systemd的其他命令

前文已经介绍了systemd在系统初始化中起到的作用和服务的管理和配置。这里补充一下systemd的其他工具和系统进程的管理 前文 Linux学习笔记10 系统启动初始化&#xff0c;服务和进程管理&#xff08;上&#xff09;-CSDN博客 Linux学习笔记11 系统启动初始化&#xff0c;服务…...

NGO-CNN-BiGRU-Attention北方苍鹰算法优化卷积双向门控循环单元时间序列预测,含优化前后对比

NGO-CNN-BiGRU-Attention北方苍鹰算法优化卷积双向门控循环单元时间序列预测&#xff0c;含优化前后对比 目录 NGO-CNN-BiGRU-Attention北方苍鹰算法优化卷积双向门控循环单元时间序列预测&#xff0c;含优化前后对比预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介…...

【分布式】分布式缓存

一、什么是分布式缓存 分布式缓存是一种将缓存数据存储在多个节点上的缓存方案。它通过将数据分散存储在多个节点的内存中&#xff0c;以提高系统的读取性能、降低数据库压力和提高系统可扩展性。 二、分布式缓存的优点 优点明细提高性能&#xff1a;分布式缓存可以将数据缓…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

select、poll、epoll 与 Reactor 模式

在高并发网络编程领域&#xff0c;高效处理大量连接和 I/O 事件是系统性能的关键。select、poll、epoll 作为 I/O 多路复用技术的代表&#xff0c;以及基于它们实现的 Reactor 模式&#xff0c;为开发者提供了强大的工具。本文将深入探讨这些技术的底层原理、优缺点。​ 一、I…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

HashMap中的put方法执行流程(流程图)

1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中&#xff0c;其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下&#xff1a; 初始判断与哈希计算&#xff1a; 首先&#xff0c;putVal 方法会检查当前的 table&#xff08;也就…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

Python Einops库:深度学习中的张量操作革命

Einops&#xff08;爱因斯坦操作库&#xff09;就像给张量操作戴上了一副"语义眼镜"——让你用人类能理解的方式告诉计算机如何操作多维数组。这个基于爱因斯坦求和约定的库&#xff0c;用类似自然语言的表达式替代了晦涩的API调用&#xff0c;彻底改变了深度学习工程…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

Chromium 136 编译指南 Windows篇:depot_tools 配置与源码获取(二)

引言 工欲善其事&#xff0c;必先利其器。在完成了 Visual Studio 2022 和 Windows SDK 的安装后&#xff0c;我们即将接触到 Chromium 开发生态中最核心的工具——depot_tools。这个由 Google 精心打造的工具集&#xff0c;就像是连接开发者与 Chromium 庞大代码库的智能桥梁…...