使用 Java 的 ArrayList 踩过的那些坑

平时开发中,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,所以修改原集合或者子集合的值,就会发生相互影响的情况了。

Guess you like

Origin blog.csdn.net/j1231230/article/details/115325530