Arrays.asList和ArrayList.subList,集合添加/修改遇到的问题

Arrays.asList

List<Integer> statusList = Arrays.asList(1,2); //底层源码返回的ArrayList,并不是java.util包下的
System.out.println(statusList);//[1,2]
System.out.println(statusList.contains(1));//true
System.out.println(statusList.contains(3));//false

/**
	添加元素到集合中,并没有返回true,而是报异常
	因为此处的Arrays.asList(1,2)返回的ArrayList却是Arrays类的内部类
	也继承了AbstractList类,重写了很多方法,比如上面使用的contains方法,但是却没有重写add方法,
*/
statusList.add(3);
System.out.println(statusList.contains(3));//java.lang.UnsupportedOperationException

总结:

使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。

ArrayList.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);

//subList返回的是bookList中索引从fromIndex(包含)到toIndex(不包含)的元素集合
System.out.println(luyaoBookList);//[人生,平凡的世界]

注意:

  • 修改原集合元素的值,会影响子集合
  • 修改原集合的结构,会引起ConcurrentModificationException异常
  • 修改子集合元素的值,会影响原集合
  • 修改子集合的结构,会影响原集合
// 修改原集合的值,影响到了子集合
bookList.set(3,"路遥-人生");

System.out.println(bookList);
System.out.println(luyaoBookList);
// 往原集合中添加元素,在遍历子集合时,发生了ConcurrentModificationException异常
bookList.add("早晨从中午开始");

System.out.println(bookList);
System.out.println(luyaoBookList);

以上异常并不是在添加元素时发生的,而是在添加元素后,遍历子集合时发生的

// 修改子集合的值,影响到了原集合
luyaoBookList.set(1,"路遥-平凡的世界");

System.out.println(bookList);
System.out.println(luyaoBookList);
// 往子集合中添加元素,影响到了原集合bookList。
luyaoBookList.add("早晨从中午开始");

System.out.println(bookList);
System.out.println(luyaoBookList);

总结:

SubList类是ArrayList的内部类,该构造函数中也并没有重新创建一个新的ArrayList,所以修改原集合或者子集合的元素的值,是会相互影响的。
ArrayList的subList方法,返回的是原集合的一个子集合(视图),非结构性修改任意一个集合的元素的值,都会彼此影响,结构性修改原集合时,会报ConcurrentModificationException异常,结构性修改子集合时,会影响原集合,所以使用时要注意,避免程序错误或者异常。