在某些情況下,我們需要對List集合取子集合,再對子集合進行一系列操作。例如:
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
List<String> subList=list.subList(1, 3);
subList.add("qq");
subList.add("ww");
System.out.println(list); //結果:[a, b, c, qq, ww, d, e, f]
System.out.println(subList); //結果:[b, c, qq, ww]
通過上述代碼發現在對子集合subList進行操作的時候,原集合list也進行了相同的操作。檢視JDK1.8版本的ArrayLis中subList的源碼:
//ArrayList中subList方法源碼
public List<E> subList(int fromIndex, int toIndex) {
subListRangeCheck(fromIndex, toIndex, size);
return new SubList(this, 0, fromIndex, toIndex);
}
發現傳回的是SubList類型的對象,該對象是ArrayList類中的私有内部類的對象,并且把參數this也就是上面例子中的list傳遞給了SubList的構造函數。以下是SubList類的源碼:
private class SubList extends AbstractList<E> implements RandomAccess {
private final AbstractList<E> parent;
private final int parentOffset;
private final int offset;
int size;
SubList(AbstractList<E> parent,
int offset, int fromIndex, int toIndex) {
this.parent = parent;
this.parentOffset = fromIndex;
this.offset = offset + fromIndex;
this.size = toIndex - fromIndex;
this.modCount = ArrayList.this.modCount;
}
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
.....
}
SubList把傳遞進來的list作為自己的屬性,也就是parent引用就指向了開頭例子中的對象list,而Sublist類中的add等方法都用parent進行了操作,也就是都用了原集合list進行了操作,是以對subList增删等操作其實内部是在對list進行操作。
是以在使用subList方法時,在對子集合進行修改元素時,要想清楚是否需要改變原有集合。如果不需要改變原有集合,可以使用如下方法處理:
public class Test {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
list.add("e");
list.add("f");
List<String> tempList=new ArrayList<String>(list.subList(1, 3));
tempList.add("qq");
tempList.add("ww");
System.out.println("list: "+list); //結果:[a, b, c, d, e, f]
System.out.println("tempList: "+tempList); //結果:[b, c, qq, ww]
}
}