最近在項目中遇到了一個問題,由一個對象序列化的結構,在反序列化時一直提示失敗,真的百思不得其解啊。在對問題排查了好久之后,才發現是這個序列化的對象中的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