Arrays.asList和ArrayList.subList
目录
asList使用add方法不受支持
subList子集原集互相影响
修改集合内容
修改集合结构
修改子集合的值
修改子集合结构
原因分析
分享两个东西,个人觉得比较容易踩坑的,也是下午的时候发现带的新人踩的坑
Arrays.asList和ArrayList.subList
asList使用add方法不受支持
我们先写一段这样的代码
public static void main(String[] args) {
List<Integer> sub = Arrays.asList(1, 2);
System.out.println(sub);
System.out.println(sub.contains(1));
System.out.println(sub.contains(3));
}
输出结果会是
true,false
这个很简单对吧
那,我们往这个sub里添加一个元素试试
可以看到,报错了
没有研究过的或者没有碰到过的,估计会懵一下,为啥只是一个简单的添加元素,但是不支持呢?
我们来看一下Arrays.asList的源码
它返回了一个ArrayList,看着是不是没问题,那,再看看这个ArrayList是个啥
你会发现,这个ArrayList是个Arrays的内部类,它也继承了AbstractList类,重写了很多方法,比如上面用的contains,但是,却没有重写add方法,所以在调用add方法的时候,会抛出java.lang.UnsupportedOperationException
subList子集原集互相影响
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<String> sub = list.subList(2, 4);
System.out.println(list);
System.out.println(sub);
}
输出结果3和4,所以List的subList方法是左边包含右边不包含,这个很容易看出来
修改集合内容
我们修改一下子集
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<String> sub = list.subList(2, 4);
System.out.println(list);
System.out.println(sub);
list.set(2, "33");
System.out.println("list修改后的list" + list);
System.out.println("list修改后的sub" + sub);
}
可以看到,哪怕截取了子集合出来,原集合修改了,子集合也会被修改
修改集合结构
猜一下结果是什么
在修改了集合结构后,遍历子集合,会抛出异常
修改子集合的值
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<String> sub = list.subList(2, 4);
System.out.println(list);
System.out.println(sub);
sub.set(0, "33");
System.out.println("sub修改后的list" + list);
System.out.println("sub修改后的sub" + sub);
}
看,修改了子集合的值,会影响原集合
修改子集合结构
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("1");
list.add("2");
list.add("3");
list.add("4");
list.add("5");
list.add("6");
List<String> sub = list.subList(2, 6);
System.out.println(list);
System.out.println(sub);
sub.add("7");
System.out.println("sub添加后的list" + list);
System.out.println("sub添加后的sub" + sub);
}
原因分析
我们看一下sublist的源码
可以看到,new了一个sublist
从这儿可以得到,subList是ArrayList的一个内部类,并且构造函数里,没有创建新的list,所以修改原集合或者子集合的元素的值,是会相互影响的
ArrayList的subList方法,返回的是原集合的一个子集合(视图),非结构性修改任意一个集合的元素的值,都会彼此影响,结构性修改原集合时,会报ConcurrentModificationException异常,结构性修改子集合时,会影响原集合,所以使用时要注意