工作中的有些场景会用到subList,但是如果没有正确的使用,可能会出现以下场景的问题,请看例子:
public static void main(String[] args) { List<Integer> listOri = new ArrayList<>(); listOri.add(1); listOri.add(2); listOri.add(3); listOri.add(4); listOri.add(5); List<Integer> listSub = listOri.subList(0, 3); System.out.println("ori:" + listOri.size()); System.out.println("sub:" + listSub.size()); listSub.add(6); System.out.println("after sub add"); System.out.println("ori:" + listOri.size()); System.out.println("sub:" + listSub.size()); listOri.add(7); System.out.println("after ori add"); System.out.println("ori:" + listOri.size()); System.out.println("sub:" + listSub.size()); }
代码中,我先是初始化了list,然后正常使用subList,然后分别对subList和list进行新增操作,并打印出他们的size,运行结果如下:
ori:5
sub:3
after sub add
ori:6
sub:4
after ori add
ori:7
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1169)
at java.util.ArrayList$SubList.size(ArrayList.java:998)
at com.vivo.exappstore.api.service.impl.SearchServiceImpl.main(SearchServiceImpl.java:228)
解释一下原因:
首先subList的add等操作是对原始list进行操作,并把操作后的modCount赋给自己
public void add(int index, E e) {
rangeCheckForAdd(index);
checkForComodification();
parent.add(parentOffset + index, e);
this.modCount = parent.modCount;
this.size++;
}
其次subList获取size时会对modCount做校验,并且校验的是原始list和自己是否相等
public int size() {
checkForComodification();
return size;
}
private void checkForComodification() {
if (ArrayList.this.modCount != this.modCount)
throw new ConcurrentModificationException();
}
因此当对原始的list进行add的时候,subList的modCount感知不到,会导致subList的checkForComodification失败
生成subList后对原始list进行增删改需要小心