前沿技术早知道,弯道超车有希望

积累超车资本,从关注DD开始

作者:申城异乡人, 图文编辑:xj

来源:https://blog.csdn.net/zwwhnly/article/details/109583990

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开发手册》泰山版(关注公众号程序猿DD,发送关键词“泰山”可以免费领取)中,也有提及:

使用工具类 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开发手册》泰山版(关注公众号程序猿DD,发送关键词“泰山”可以免费领取)中是这样描述的:

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。

最近整理了一份最新的面经资料,里面收录了2021年各个大厂的面试题,年后打算跳槽的小伙伴不要错过,点击领取吧!

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开发手册》泰山版(关注公众号程序猿DD,发送关键词“泰山”可以免费领取)中是这样描述的:

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("早晨从中午开始");//包括C++、java、Python、JavaScript等各种语言,还有操作系统、数据结构、设计、网络等各方面的学习资料。就像金庸小说中琅嬛福地,什么都有的计算机经典书籍大合集,赶快来这里领取吧
//https://mp.weixin.qq.com/s/vc25ZzSonPhcBwTlbUcYkQSystem.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异常,结构性修改子集合时,会影响原集合,所以使用时要注意,避免程序错误或者异常。

对了,我们创建了一个高质量的技术交流群,与优秀的人在一起,自己也会优秀起来,赶紧点击加群,享受一起成长的快乐。

推荐阅读

  • 扔掉 Postman,Apifox 才是 YYDS!

  • 我妈今年 70 岁,受不了Windows蓝屏,用了 21 年的 Linux!YYDS!

  • FTC 警告:Log4j2 的漏洞还不修,或将被采取法律行动...

前沿技术早知道,弯道超车有希望

积累超车资本,从关注DD开始

点击阅读原文,送你免费Spring Boot教程!

使用Arrays.asList、ArrayList的subList时,你有踩过这些坑吗?相关推荐

  1. Unity2020打包安卓时配置环境踩过的坑(JDKSDKNDKGradle详解)

    之前的打包环境都是吃现成的, 这次新公司需要自己配置,踩了坑记录一下,以防之后遗忘. 如果是 用Hub管理的项目 可以通过Hub 去下载 安装内置的Open JDK ,SDK 等很方便也稳定. 没有用 ...

  2. 后端:请谨慎使用Arrays.asList、ArrayList的subList

    1. 使用Arrays.asList的注意事项 1.1 可能会踩的坑 先来看下Arrays.asList的使用: List<Integer> statusList = Arrays.asL ...

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

    1. 使用Arrays.asList的注意事项 1.1 可能会踩的坑 先来看下Arrays.asList的使用: List<Integer> statusList = Arrays.asL ...

  4. 在项目中用了Arrays.asList、ArrayList的subList,被老大公开批评

    推荐阅读:这几个已经淘汰的Java技术,请不要在继续学了!!! 使用Arrays.asList的注意事项 1.可能会踩的坑 先来看下Arrays.asList的使用: List<Integer& ...

  5. 在项目中使用Arrays.asList、ArrayList的subList,被老大点名批评~

    1. 使用Arrays.asList的注意事项 1.1 可能会踩的坑 先来看下Arrays.asList的使用: List<Integer> statusList = Arrays.asL ...

  6. Arrays.asList的使用

    一.java.util.Arrays.asList() 的一般用法 如果将一个数组转换为 List,可以将需要转化的数组作为参数,或者直接把数组元素作为参数.但是其中参数必须是包装类类型,如果使用的是 ...

  7. ArrayList.subList() VS Arrays.asList :创业更比守业难?

    2021年7月12日张近东辞去苏宁董事长并提名张康阳为非独立董事.张近东的黯然退场犹如2017年的王健林.那么在时代更迭的过程中,他们的儿子又会以怎样的姿态立住脚跟? 王思聪和张康阳就像一个班级里的坏 ...

  8. java 集合数组初始化_Java用Arrays.asList初始化ArrayList实例方法

    Java用Arrays.asList初始化ArrayList实例方法 发布于 2020-2-29| 复制链接 在本篇文章里小妖给大家分享的是关于Java中使用Arrays.asList初始化Array ...

  9. Arrays.asList()返回的ArrayList,这是Arrays里内嵌的一个私有静态类,而并不是java.util.ArrayList类

    测试代码: package array;import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; ...

最新文章

  1. SpringCloud组件 源码剖析:Eureka服务注册方式流程全面分析
  2. java超时自动关闭_[Java教程]web页面超时自动退出方法_星空网
  3. pandaboard 安装_linux fb设备(pandaboard) | 学步园
  4. (JAVA)CollectionDemo1
  5. linux内核ddr初始化,X-007-UBOOT-DDR的初始化(Bubblegum-96平台)
  6. Kubernetes-保障集群内节点和网络安全
  7. weblogic时间问题
  8. 剑指offer——数组中重复的数字
  9. 专用集成电路设计实用教程(学习笔记一)
  10. 软考高项-案例分析背诵
  11. 从Unity导出Obj格式的地形(Terrian)
  12. 实验二:递归下降语法分析
  13. R语言绘图—一键添加显著性
  14. 差分管电路图_最简单的单差分OCL功放电路图(四款单差分OCL功放电路设计原理图详解)...
  15. hd6630m可以玩lol吗_《LOL》流畅玩!Intel HD620核显性能实测
  16. Ubuntu 20.04.3 “have unmet dependencies“
  17. python实现电话簿
  18. 利用pyecharts的wordcloud实现词云(可结合Pandas数据分析和jieba分词)
  19. 5. (go语言)函数
  20. 计算机中的位运算—正数,负数,原码,反码,补码

热门文章

  1. 【VBA技巧】不打开Excel读取数据
  2. 【Python beautiful soup】如何用beautiful soup 解析HTML内容
  3. 一文带你看懂拉曼光谱
  4. InnoDB双写缓冲
  5. Vue的demo-踩坑
  6. 基于http的cookie和JSON储存
  7. H3C路由器PPPoE拨号 IPv6地址一直显示[TENTATIVE]的故障
  8. Android 四大组件丨BroadcastReceiver
  9. 为什么华为加班那么多?
  10. 科研信息基础设施的运行治理模式研究