前言
集合是日常工作中几乎每天都在用的玩意,也是八股文中被翻烂的东西,诸如List、Map,确实很重要也很实用,但是不注意细节就比较容易踩坑。比较常见的就是今天要整理的Arrays.asList和ArrayList.subList。不是什么高深的东西,日常一整理。
最常用的写法
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
使用Arrays.asList的注意事项
踩坑的大部分原因
图方便,有时候对于少量的几个元素,心想着这不是有现成的方法吗,好,梭哈
List<Integer> statusList = Arrays.asList(1, 2);
不好意思,这确实没少毛病。上线后一段时间,需要加n个元素,看到有集合,easy,好,在原来的基础上继续梭哈,代码变成这样
List<Integer> statusList = Arrays.asList(1, 2);
statusList.add(3);
上线后,boom!检查问题,还死鸭子嘴硬,这代码这么简单,肯定不是这个地方出错,看一下报错:
原因分析
点进去,看一下Arrays类提供的静态方法asList的源码:
细心一看,就会发现此ArrayList并不是我们经常使用的ArrayList,因为我们平时经常使用的ArrayList是位于java.util包下的:
但是此处的ArrayList却是Arrays类的内部类,继续看看他的继承类,
它也继承了AbstractList类,重写了很多方法,比如我们上面使用的contains方法,但是却没有重写add方法,所以我们在调用add方法时才会抛出java.lang.UnsupportedOperationException异常。
在《阿里巴巴Java开发手册》泰山版中,有说明这个注意点:
使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
小结
简单场合可以使用Arrays.asList,比如快速声明一个集合,判断某个值是否在允许的范围内,但是不要调用他的修改方法,实在要用,先看看是否有重新对应的方法。
使用ArrayList的subList的注意事项
先看个Demo
List<String> bookList = new ArrayList<>();
bookList.add("天道");
bookList.add("倚天屠龙记");
bookList.add("阿甘正传");
bookList.add("你好,明天");
bookList.add("我是谁");
List<String> subBookList = bookList.subList(3, 5);
System.out.println(bookList);
System.out.println(subBookList);
执行结果如下:
从运行结果可以看出,subList返回的是bookList中索引从fromIndex(包含)到toIndex(不包含)的元素集合。
使用起来很简单,主要有以下几点要注意,否则会造成程序错误或者异常:
-
修改原集合元素的值,会影响子集合 -
修改原集合的结构,会引起ConcurrentModificationException异常 -
修改子集合元素的值,会影响原集合 -
修改子集合的结构,会影响原集合 以上几点在《阿里巴巴Java开发手册》泰山版中是这样描述的:
修改原集合的值,会影响子集合
如下验证:
可以看出,虽然我们只是修改了原集合bookList的值,但是影响到了子集合subBookList
修改原集合的结构,会引起ConcurrentModificationException异常
温馨提醒:其实装好相关的插件,会自然提示可能出现的异常,可以整一下
修改子集合的值,会影响原集合
修改子集合的结构,会影响原集合
原因分析
看下subList方法的注释,了解下它的用途:
-
简单理解:返回指定的{@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,所以修改原集合或者子集合的元素的值,是会相互影响的。
写在最后
好了,明白了是什么原因了吧。不要图方便,不看清他的原理。这里是"安前码后",一个分享实用内容的号,觉得用心整理的,帮忙给个三连。更多内容持续输出中。
本文由 mdnice 多平台发布