平时开发中,ArrayList 的使用频率是相当高的,但一不小心就容易踩坑,在这里记录一下。
1. 使用 Arrays.asList 的坑
使用场景
正常使用 Arrays.asList 不会有太大问题
List<Integer> testList = Arrays.asList(1, 2, 3);
添加一个元素,理想状态会输出结果:true
testList.add(4);
System.out.println(testList.contains(4));
实际运行却会报错:
分析
正常我们使用的 ArrayList 是 java.util 下的,而查看源码可以发现,asList 返回的 ArrayList 实际上是 Arrays 类的内部类,而这个内部类没有重写 add 方法,所以会报错。
所以科学的使用姿势是,在声明后就不要再调用 add 方法修改集合,可以提前修改后再进行转换。
2. 使用 ArrayList 的 subList 的坑
使用场景
(1). 修改原集合的值,会影响子集合
List<String> testList = new ArrayList<>();
testList.add("123");
testList.add("456");
testList.add("789");
List<String> subList = testList.subList(1, 3);
System.out.println(testList);
System.out.println(subList);
// 修改原集合的值
testList.set(2,"222");
System.out.println(testList);
System.out.println(subList);
输出结果:
(2). 原集合添加值,子集合遍历会报错
List<String> testList = new ArrayList<>();
testList.add("123");
testList.add("456");
testList.add("789");
List<String> subList = testList.subList(1, 3);
System.out.println(testList);
System.out.println(subList);
// 原集合添加新的值
testList.add("222");
System.out.println(testList);
System.out.println(subList);
运行程序会报错:
(3). 子集合添加或修改值,会影响原集合
List<String> testList = new ArrayList<>();
testList.add("123");
testList.add("456");
testList.add("789");
List<String> subList = testList.subList(1, 3);
System.out.println(testList);
// 子集合添加值
subList.add("222");
// 子集合修改值
subList.set(0, "000");
System.out.println(testList);
会发现原集合也发生了改变:
分析
查看一下 subList 的源码:
发现调用了 SubList 类的构造函数:
这里的构造函数并没有重新创建 ArrayList,所以修改原集合或者子集合的值,就会发生相互影响的情况了。