ArrayList的 subList ( int fromIndex, int toIndex ) 方法执行结果是获取ArrayList的一部分,返回的是ArrayList的部分视图。《阿里巴巴Java开发手册》中对subList方法的使用有规定:
首先通过一个例子,初步了解subList的用法和易出错的地方:
import java.util.ArrayList;
import java.util.List;
public class SubListDemo {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
list.add(i);
}
System.out.println("原:" + list);
List<Integer> subList = list.subList(0, 5);
System.out.println("子:" + subList);
// subList的add()方法
subList.add(3, 21);
// 输出原集合
System.out.println("==============subList的add()方法执行结果====================");
System.out.println("原:" + list);
// 输出subList
System.out.println("子:" + subList);
// ArrayList的add()方法
list.add(31);
// 输出原集合
System.out.println("==============ArrayList的add()方法执行结果====================");
System.out.println("原:" + list);
// 输出subList
System.out.println("子:" + subList);
}
}
程序的执行结果为:
从结果得出:
- 对子类subList的操作会反映到父类中。
- 使用父类的方法(能改变modCount值的方法)修改集合会导致子类的遍历抛出 ConcurrentModificationException 异常。
程序的执行结果也验证了阿里手册的规定,下面,通过源码解析更加清晰的理解这两条规定的用意。
ArrayList 的 subList 方法返回的一个内部类 SubList,返回的 List 中,下标范围在[fromIndex, toIndex) 之间:
public List<E> subList(int fromIndex, int toIndex) {
// 参数检查
subListRangeCheck(fromIndex, toIndex, size);
// 内部类SubList,this为父类的引用,0 表示父类下标偏移量
return new SubList(this, 0, fromIndex, toIndex);
}
subListRangeCheck(fromIndex, toIndex, size);方法检查两个下标是否合规:
static void subListRangeCheck(int fromIndex, int toIndex, int size) {
if (fromIndex < 0)
throw new IndexOutOfBoundsException("fromIndex = " + fromIndex);
if (toIndex > size)
throw new IndexOutOfBoundsException("toIndex = " + toIndex);
if (fromIndex > toIndex)
throw new IllegalArgumentException("fromIndex(" + fromIndex +
") > toIndex(" + toIndex + ")");
}
SubList 内部类,继承了 AbstractList 类,并实现了 RandomAccess 接口,支持随机读取: