生成子列表后不要再直接操作原列表了
Updated:
参考:《改善java程序的151个建议》
http://blog.csdn.net/chenssy/article/details/44102915
- 我们知道subList生成的子列表只是原列表的一个视图而已,如果我们操作子列表它产生的作用都会在原列表上面表现,但是如果我们操作原列表会产生什么情况呢?
1 | 1. public static void main(String[] args) { |
subList的size方法出现了异常,而且还是并发修改异常。。。。。。这里没有使用多线程操作,何来的并发修改呢?
我们在来看看subList的size方法:1
2
3
4
5
6
7
8
9
101. public int size() {
2. checkForComodification();
3. return this.size;
4. }
size方法首先会通过checkForComodification验证,然后再返回this.size。该方法就是用于检测是否并发修改的。
1. private void checkForComodification() {
2. //判断当前修改计数器是否与子列表生成时一致
3. if (ArrayList.this.modCount != this.modCount)
4. throw new ConcurrentModificationException();
5. }
该方法表明当原列表的modCount与this.modCount不相等时就会抛出ConcurrentModificationException。同时我们知道modCount 在new的过程中 “继承”了原列表modCount,只有在修改该列表(子列表)时才会修改该值(先表现在原列表后作用于子列表)。而在该实例中我们是操作原列表,原列表的modCount当然不会反应在子列表的modCount上啦,所以才会抛出该异常。
subList的其他方法也会检测修改计数器,若生成子列表后再直接修改了原列表,这些方法会抛出ConcurrentModificationException 异常。
对于子列表视图,它是动态生成的,生成之后就不要操作原列表了,否则必然都导致视图的不稳定而抛出异常。最好的办法就是将原列表设置为只读状态,要操作就操作子列表:
1 | 1. List<Integer> list3 = list1.subList(0, 1); |
还有个问题:
List可以生成多个子列表,但问题是只要生成的子列表多于一个,则任何一个子列表都不能修改了否则抛出并发修改异常。
1 | public static void main(String[] args) { |