天天看點

關于ArrayList中的subList方法需要注意的地方

在某些情況下,我們需要對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]
	}

}