这个结论对于我们日常的开发工作, 倒是起不到太大的帮助作用. 因为这些结论总结出的都是消极的结果, 而不是积极的结果. 不过, 这个结论倒是告诉我们:

如果你对一个 List 进行过 subList() 的操作之后, 

1. 千万不要再对原 List 进行任何改动的操作(例如: 增删改), 查询和遍历倒是可以. 因为如果对原 List 进行了改动, 那么后续只要是涉及到子 List 的操作就一定会出问题. 而至于会出现什么问题呢? 具体来说就是: 
(1) 如果是对原 List 进行修改 (即: 调用 set() 方法) 而不是增删, 那么子 List 的元素也可能会被修改 (这种情况下不会抛出并发修改异常). 
(2) 如果是对原 List 进行增删, 那么此后只要操作了子 List , 就一定会抛出并发修改异常.

2. 千万不要直接对子 List 进行任何改动的操作(例如: 增删改), 但是查询和间接改动倒是可以. 不要对子 List 进行直接改动, 是因为如果在对子 List 进行直接改动之前, 原 List 已经被改动过, 那么此后在对子 List 进行直接改动的时候就会抛出并发修改异常.

 

既然获取子 List 后会有这么多限制条件, 一不小心就会出错, 那我们还怎么操作这个子 List 呢? 或者说, 怎样才能安全地操作子 List 呢? 其实, 你可能已经注意到了我在上述结论中提到的间接二字. 是的, 我们可以通过间接的方式来安全地操作子 List . 怎么间接呢? 其实, “间接” 和 “直接” 是相对的, 因为根据前边的分析, 子 List 会共用原 List 中后一部分的元素, 他们共同指向相同的对象, 这种共用对象的特性就是导致产生各种不安全结果的罪魁祸首. 如果我们将二者分别指向不同的对象, 岂不是就能避免不安全结果的产生? 也就是说, 我们需要让子 List 指向新的对象, 并且让新对象每个位置上的数值要和原 List 中相关位置上的数值相等即可. 于是就想到了以下两种间接的处理方式:

  1. 创建一个新的对象作为我们最终要操作的对象, 在其构造方法中, 将通过 subList() 方法获取到的子 List 作为该构造方法的参数传入. 这时, 这个新对象内所包含的元素和子 List 的完全相同, 但却指向的是不同的对象. 我们只需使用这个新创建的对象即可. 
    对于 ArrayList
List<Integer> subList = new ArrayList<>(list.subList(2, list.size()));

对于 LinkedList

List<Integer> subList = new LinkedList<>(list.subList(2, list.size()));
  1. 创建一个新的对象作为我们最终要操作的对象, 然后调用这个新对象的 addAll() 方法, 将通过 subList() 方法获取到的子 List 作为 addAll() 方法的参数传入, 这时, 这个新对象内所包含的元素和子 List 的完全相同, 但却指向的是不同的对象. 我们只需使用这个新创建的对象即可. 
    对于 ArrayList:
List<Integer> subList = new ArrayList<>();  
subList.addAll(list.subList(2, list.size()));

对于 LinkedList:

List<Integer> subList = new LinkedList<>();  
subList.addAll(list.subList(2, list.size()));