ArrayList的subList方法帶來的坑


最近在項目中遇到了一個問題,由一個對象序列化的結構,在反序列化時一直提示失敗,真的百思不得其解啊。在對問題排查了好久之后,才發現是這個序列化的對象中的list調用了ArrayList的sublist方法存入導致的問題,真的是滿滿的坑,sublist還是要慎重使用的啊,下面詳細介紹下sublist。

以下內容轉自:ArrayList的subList方法

List接口中定義:

List<E> subList(int fromIndex, int toIndex);

英文注釋:

復制代碼
Returns a view of the portion of this list between the specified fromIndex, inclusive, and toIndex, exclusive. (If fromIndex and toIndex are equal, the 
returned list is empty.) The returned list is backed by this list, so non-structural changes in the returned list are reflected in this list, and vice-versa.
The returned list supports all of the optional list operations supported by this list.
This method eliminates the need for explicit range operations (of the sort that commonly exist for arrays). Any operation that expects a list can be used as a
range operation by passing a subList view instead of a whole list. For example, the following idiom removes a range of elements from a list: list.subList(from, to).clear(); Similar idioms may be constructed for indexOf and lastIndexOf, and all of the algorithms in the Collections class can be applied to a subList. The semantics of the list returned by this method become undefined if the backing list (i.e., this list) is structurally modified in any way other than via
the returned list. (Structural modifications are those that change the size of this list, or otherwise perturb it in such a fashion that iterations in
progress may yield incorrect results.)
復制代碼

根據注釋得知:

1,該方法返回的是父list的一個視圖,從fromIndex(包含),到toIndex(不包含)。fromIndex=toIndex 表示子list為空

2,父子list做的非結構性修改(non-structural changes)都會影響到彼此:所謂的“非結構性修改”,是指不涉及到list的大小改變的修改。相反,結構性修改,指改變了list大小的修改。

3,對於結構性修改,子list的所有操作都會反映到父list上。但父list的修改將會導致返回的子list失效。

4,tips:如何刪除list中的某段數據:

list.subList(from, to).clear();

示例代碼:

來自【Java每日一題】20170105,就是看到這個題目才讓我知道list的這個方法我沒有接觸過

復制代碼
package ques;  
  
import java.util.ArrayList;  
import java.util.List;  
  
public class Ques0105 {  
  
    public static void main(String[] args) {  
        List<String> list = new ArrayList<String>();  
        list.add("a");  
  
        // 使用構造器創建一個包含list的列表list1  
        List<String> list1 = new ArrayList<String>(list);  
        // 使用subList生成與list相同的列表list2  
        List<String> list2 = list.subList(0, list.size());  
        list2.add("b");  
  
        System.out.println(list.equals(list1));  
        System.out.println(list.equals(list2));  
    }  
}
復制代碼

返回結果如下:

可以發現,list2為list的子list,當list2發生結構性修改(list2.add("b"))后,list也發生相應改變,所以返回結果為false和true


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM