为什么要谨慎使用Arrays.asList、ArrayList的subList?

基于Simulink的输入-输出线性化精确转矩控制 本文详细介绍了基于Simulink的永磁同步电机(PMSM)输入-输出线性化(IOL)精确转矩控制方法。针对传统解耦控制在非线性转矩特性下的局限性,通过建立PMSM非线性状态空间模型,设计IOL控制器将系统转化为线性输入-输出映射。文章包含系统原理推导、Simulink建模步骤、参数整定方法和仿真结果分析,验证了IOL在高动态、宽速域工况下的优越性能(转矩误差降低90%)。最后提出了工程实现要点和扩展应用方向,为开发高精度电机驱动系统提供了实用指导。 阅读详情

1. 使用Arrays.asList的注意事项

1.1 可能会踩的坑

先来看下Arrays.asList的使用:

List<Integer> statusList = Arrays.asList(1, 2);
System.out.println(statusList);
System.out.println(statusList.contains(1));
System.out.println(statusList.contains(3));

输出结果如下图所示:

然后,往statusList中添加元素3,如下所示:

statusList.add(3);
System.out.println(statusList.contains(3));

预期的结果,应该是输出true,但是实际却是抛出了java.lang.UnsupportedOperationException异常:

不禁疑问,只是简单添加个元素,为啥会抛这么个异常呢,不科学啊。

1.2 原因分析

带着这个疑问,我们看下Arrays类提供的静态方法asList的源码:

返回的是ArrayList,很熟悉,有木有,但是再细心一看,就会发现此ArrayList并不是我们经常使用的ArrayList,因为我们平时经常使用的ArrayList是位于java.util包下的:

但是此处的ArrayList却是Arrays类的内部类:

它也继承了AbstractList类,重写了很多方法,比如我们上面使用的contains方法,但是却没有重写add方法,所以我们在调用add方法时才会抛出java.lang.UnsupportedOperationException异常。

关于这一点,在《阿里巴巴Java开发手册》泰山版中,也有提及:

使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

所以大家在使用Arrays.asList时还是要注意下,避免踩坑。

1.3 总结

Arrays.asList方法可以在一些简单的场合使用,比如快速声明一个集合,判断某个值是否在允许的范围内:

但声明后不要再调用add等方法修改集合,否则会报java.lang.UnsupportedOperationException异常。

2. 使用ArrayList的subList的注意事项

先来看下subList的简单使用:

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

运行结果如下图所示:

从运行结果可以看出,subList返回的是bookList中索引从fromIndex(包含)到toIndex(不包含)的元素集合。

使用起来很简单,也很好理解,不过还是有以下几点要注意,否则会造成程序错误或者异常:

  1. 修改原集合元素的值,会影响子集合
  2. 修改原集合的结构,会引起ConcurrentModificationException异常
  3. 修改子集合元素的值,会影响原集合
  4. 修改子集合的结构,会影响原集合

以上几点在《阿里巴巴Java开发手册》泰山版中是这样描述的:

2.1 修改原集合的值,会影响子集合

比如,我们修改下原集合bookList中某一元素的值(非结构性修改):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 修改原集合的值
bookList.set(3,"路遥-人生");

System.out.println(bookList);
System.out.println(luyaoBookList);

运行结果如下所示:

可以看出,虽然我们只是修改了原集合bookList的值,但是影响到了子集合luyaoBookList。

2.2 修改原集合的结构,会引起ConcurrentModificationException异常

比如,我们往原集合bookList中添加一个元素(结构性修改):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 往原集合中添加元素
bookList.add("早晨从中午开始");

System.out.println(bookList);
System.out.println(luyaoBookList);

运行结果如下所示:

可以看出,当我们往原集合中添加了元素(结构性修改)后,在遍历子集合时,发生了ConcurrentModificationException异常。

注意事项:以上异常并不是在添加元素时发生的,而是在添加元素后,遍历子集合时发生的。

关于这一点,在《阿里巴巴Java开发手册》泰山版中是这样描述的:

2.3 修改子集合的值,会影响原集合

比如,我们修改下子集合luyaoBookList中某一元素的值(非结构性修改):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 修改子集合的值
luyaoBookList.set(1,"路遥-平凡的世界");

System.out.println(bookList);
System.out.println(luyaoBookList);

运行结果如下所示:

可以看出,虽然我们只是修改了子集合luyaoBookList的值,但是影响到了原集合bookList。

2.4 修改子集合的结构,会影响原集合

比如,我们往子集合luyaoBookList中添加一个元素(结构性修改):

List<String> bookList = new ArrayList<>();
bookList.add("遥远的救世主");
bookList.add("背叛");
bookList.add("天幕红尘");
bookList.add("人生");
bookList.add("平凡的世界");

List<String> luyaoBookList = bookList.subList(3, 5);

System.out.println(bookList);
System.out.println(luyaoBookList);

// 往子集合中添加元素
luyaoBookList.add("早晨从中午开始");

System.out.println(bookList);
System.out.println(luyaoBookList);

运行结果如下所示:

可以看出,当我们往子集合中添加了元素(结构性修改)后,影响到了原集合bookList。

2.5 原因分析

首先,我们看下subList方法的注释,了解下它的用途:

Returns a view of the portion of this list between the specified {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.

翻译过来意思就是:

返回指定的{@code fromIndex}(包含)和{@code toIndex}(排除)之间的列表部分的视图。

然后,我们看下它的源码:

public List<E> subList(int fromIndex, int toIndex) {
    subListRangeCheck(fromIndex, toIndex, size);
    return new SubList(this, 0, fromIndex, toIndex);
}

可以看到,它调用了SubList类的构造函数,该构造函数的源码如下图所示:

可以看出,SubList类是ArrayList的内部类,该构造函数中也并没有重新创建一个新的ArrayList,所以修改原集合或者子集合的元素的值,是会相互影响的。

2.6 总结

ArrayList的subList方法,返回的是原集合的一个子集合(视图),非结构性修改任意一个集合的元素的值,都会彼此影响,结构性修改原集合时,会报ConcurrentModificationException异常,结构性修改子集合时,会影响原集合,所以使用时要注意,避免程序错误或者异常。

【架构】-- StarRocks 和 Doris 介绍与选型建议 查询性能 | ✅ 高性能,支持向量化执行和 CBO 优化器 | ✅ 高性能,优化的查询引擎 |- **实时性要求高**:如果业务对数据的实时性要求较高,建议选择 **StarRocks**,其在实时数据处理和低延迟查询方面表现优越。- **复杂查询需求**:对于需要处理复杂多表关联查询的场景,两者均可胜任,需根据具体性能测试结果进行选择。 阅读详情

相关推荐

【黑马点评优化】2-Canel实现多级缓存(Redis+Caffeine)同步

【黑马点评优化】2-Canel实现多级缓存(Redis+Caffeine)同步

m0_52031708的博客 3857

Java Arrays.asList()详解以及为何不要使用Arrays.asList()

我只是改变list的顺序,然而数组顺序却也发生了变化,很多时候这并不是我们想要的。这个静态内部类,存储数组元素的a变量是final类型的,由此判断,这个静态内部类是不能做任何内部元素的添加删除操作的!找到异常的来源了,我们使用asList得到的对象add、remove方法直接就是抛出异常.如果要对asList得到的对象使用add、remove方法可以使用如下解决办法。原来Arrays的asList方法使用的ArrayList类是一个内部定义的类,而不是java.util.ArrayList类。

QWQ___qwq的博客 1115

测试人必看!正交表与Allpairs工具对比:如何选择最适合你的组合测试方案?

本文深入对比了正交表、PICT与Allpairs三种主流组合测试方案,帮助测试人员根据项目场景做出最佳选择。文章分析了各自的核心原理、优劣势及适用场景,特别强调了在涉及复杂约束时PICT工具的强大功能,并提供了从原理学习到CI/CD集成的实战选型指南。

weixin_29224309的博客 268

千万不要这样使用 Arrays.asList !

使用Arrays.asList()的原因无非是想将数组或一些元素转为集合,而你得到的集合并不一定是你想要的那个集合。而一开始asList的设计时用于打印数组而设计的,但j...

王不二 2083

一种基于OpenPose和DNN的跌倒检测软件系统(中文&英文)

学习并实现一种跌倒检测模型,此模型基于OpenPose实现逐帧人体姿态检测,使用DNN识别人体动作。检测方式有在线与离线两种,本文主要测试了离线模式,测试效果较好。

Tongzhou_Li的博客 2645

PredFormer实战:用Transformer搞定交通流量预测(附TaxiBJ数据集代码)

本文详细介绍了如何利用PredFormer这一基于Transformer的先进模型进行交通流量预测,特别针对TaxiBJ数据集提供了完整的实战代码和优化策略。PredFormer通过门控Transformer块(GTB)的创新设计,在时空预测任务中展现出显著优势,相比传统方法将MSE降低33.1%,推理速度提升4.4倍。文章还涵盖了模型轻量化、部署优化等实用技巧,为智慧城市建设中的交通预测提供了高效解决方案。

weixin_29194817的博客 447

Java工具类java.util.Arrays中asList()方法使用注意事项

最近看到编程规范中说:禁止对Arrays.asList()方法生成的List集合进行add、remove操作,因为会报UnsupportedOperationException。 这是为什么呢? 原来看源码发现:Arrays.asList()方法最后返回了一个ArrayList对象,那为什么我们不能调用add胡子和remove方法呢? Arrays.asList()源码如下: 注意:返回的这个ArrayList对象并不是java.util.ArrayList,而是java.util.Arrays工具类中的

阳阳的博客 1062

思澈sdk-新建lcd

co5300至此有3个同ID的驱动,在co5300xxxx.c的LCD_DRIVER_EXPORT(co5300, LCD_ID, &lcdc_int_cfg, &CO5300_drv, LCD_PIXEL_WIDTH, LCD_PIXEL_HEIGHT, 2);2 在customer\peripherals\Kconfig_lcd中添加如下配置(注意修改的地方有两个LCD_USING_TFT_CO5300_143)5 在该文件中的config LCD_DPI配置项下添加:(这里300为DPI)

gongyuan073的专栏 1392

慎用Arrays.asList和ArrayList部分坑

1、简单的使用Arrays.asList final List<Integer> integers = Arrays.asList(1, 3); 但是在初始化后我们需要在添加一个元素 integers.add(8); 我们执行代码,却发现报错了 这是为什么啦,按道理来说这不应该,简单的一个语句怎么会报错啦。 我们就来看下Arrays.asList的源码 可以发现Arrays.asList使用的new ArrayList<>(a);是自己的内部类,而不是我们平常使用的java.

weixin_42324471的博客 449

商品评论中的实体情感分析

在之前的文章中我已经将商品评论中的评价实体,也就是特征(feature)给挖掘出来了,我看了一下,挖掘的效果还是不错的。原文链接:http://blog.csdn.net/chixujohnny/article/details/52794685 下面一步要做的是施加情感因子,也就是说,要将人们评论时候所连带的感情程度施加一下。这项任务的归类应该是情感分析技术。 目前该类问题的情感分析技

chixujohnny 7974

ADS中使用Momentum进行电源完整性分析示例

这个应用可以帮助工程师用更快的时间使用ADS Momentum完成PDN分析。该应用描述了利用ADS Momentum RF模拟器进行PDN分析的方法,大大缩短了计算时间。 该分析主要应用与高速数字设计。 在此应用中使用了以下ADS特性: ADS设计流程集成(ADFI)。 电磁协同仿真。 Momentum仿真。 仿真流程如下: 在Allegro中创建ADFI文件 要将Alleg...

zb6075_lb的专栏 7013

请谨慎使用Arrays.asList、ArrayList的subList

往期热门文章:1、人脸识别“抓”错了人,他在监狱呆了 10 天 2、这四种情况下,才是考虑分库分表的时候! 3、求求你别再用offset和limit分页了 4、浅谈用不好缓存的几个受伤场...

Java之间 210

Python 爬虫实战:医学临床指南爬取(含 PDF 解析与结构化存储)

在当今数字化时代,医学临床指南作为医生进行科学诊疗的重要参考资料,包含大量经过临床验证的诊疗路径和建议。这些指南通常发布在权威医学网站上,数量庞大且更新频繁。如何自动化地抓取并存储这些指南,成为医疗数据分析、医学研究以及医疗 AI 模型训练等工作的关键第一步。本文将系统讲解如何利用 Python 爬虫技术从权威医学网站爬取临床指南内容,并实现 PDF 解析与结构化存储。

u014481728的博客 451

请谨慎使用 Arrays.asList、ArrayList 的 subList

点击上方“Java基基”,选择“设为星标”做积极的人,而不是积极废人!源码精品专栏原创 | Java 2020超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析...

weixin_44421461的博客 173

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

上一篇: 使用Java Stream,提取集合中的某一列/按条件过滤集合/求和/最大值/最小值/平均值
下一篇: 如何使用Java获取货币符号?
加班不秃顶
博客等级 码龄7年 1822粉丝 599原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值