Java的容器类ArrayList很常用,旗下存在一个subList方法,是值得注意的。
subList方法仅能够取出此ArrayList的引用,即使其看起来,好像是取出一个ArrayList的子ArrayList。
其实不然,subList方法的返回值,只是ArrayList的一个映像而已。
也就是说,当我们使用子集合subList进行元素的修改操作时,会影响原有的list集合。
比如如下的一段代码:
package subList;
import java.util.*;
public class subListTest {
public static void main(String[] args) {
List<String> arrayList = new ArrayList<String>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
List<String> arrayList_subList = arrayList.subList(0, 2);
arrayList.remove(0);
arrayList.add("d");
System.out.println(arrayList_subList.size());
}
}
将会抛出java.util.ConcurrentModificationException。
显然对原有的list集合的修改相应到subList方法返回的arrayList_subList。
Java中的subList方法,并不是提供用来生成子集合的,如果要用来生成子集合,还是采取如下的一种硬复制形式为好,而不是subList软复制:
package subList;
import java.util.ArrayList;
public class subListTest {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
ArrayList<String> arrayList_sublist = new ArrayList<String>();
for(int i=1;i<=2;i++){
arrayList_sublist.add(arrayList.get(i));
}
System.out.println(arrayList_sublist);
}
}
运行结果为:
subList方法,常见于两种方法,一种是取出ArrayList的某一段配合indexOf和lastIndexOf构造类似的语句。判断某段子集合是否符合条件。而且 Collections 类中的所有算法都可以应用于subList。如果支持列表(即此列表)通过任何其他方式(而不是通过返回的列表)从结构上修改,则此方法返回的列表语义将变为未定义。这里的“从结构上修改”是指更改列表的大小,或者以其他方式打乱列表,使正在进行的迭代产生错误的结果。
另一种是删除ArrayList的某一段集合,例如如下代码:
package subList;
import java.util.ArrayList;
public class subListTest {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<String>();
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
System.out.println(arrayList);
arrayList.subList(1,3).clear();
System.out.println(arrayList);
}
}
得到的是如下的一段结果:
abcd这个集合的1(含)-3(不含),即从0开始算起,第1、2号元素被删去了,形成了一个新的集合ab。