读阿里巴巴开发规范关于list集合操作的问题

工作清闲时候在读阿里java开发规范突然发现一个关于list集合操作有意思的点,觉的很有意思
我们都知道操作list数据集合时,如果使用迭代器并用list集合本身的remove方法移除数据时,会发生 java.util.ConcurrentModificationException 异常,
例:public class TestMain {

    public static void main(String[] args) {
        List<String> lists = new ArrayList<>();
        lists.add("a");
        lists.add("b");
       lists.add("c");
        Iterator<String> str = lists.iterator();
        while (str.hasNext()) {
         String s=  str.next();
            lists.remove(s);
        }

    }
}
结果:Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:886)
	at java.util.ArrayList$Itr.next(ArrayList.java:836)
	at TestMain.main(TestMain.java:17)
这点只要仔细读一下ArrayList源码的人都会知道原因的
private class Itr implements Iterator<E> {
    int cursor;      
    int lastRet = -1; 
    int expectedModCount = modCount;
主要就是ArrayList内部类中的
 int expectedModCount = modCount;这个变量,
public E remove(int index) {
    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}
这里面只修改了
 modCount++;
导致
public E next() {
    checkForComodification();
    int i = cursor;
    if (i >= size)
        throw new NoSuchElementException();
    Object[] elementData = ArrayList.this.elementData;
    if (i >= elementData.length)
        throw new ConcurrentModificationException();
    cursor = i + 1;
    return (E) elementData[lastRet = i];
}
方法中的checkForComodification方法校验时不通过
final void checkForComodification() {
    if (modCount != expectedModCount)
        throw new ConcurrentModificationException();
}
但是开发规范中发举了一个反例
例:public class TestMain {

    public static void main(String[] args) {
        List<String> lists = new ArrayList<>();
        lists.add("a");
        lists.add("b");
       //lists.add("c");//这行注释掉
        Iterator<String> str = lists.iterator();
        while (str.hasNext()) {
         String s=  str.next();
            lists.remove(s);
        }

    }
}
当list集合中只有两个元素时,确没有报异常,这里就会有点疑问了,仔细查看了源代码,原来问题出在这里,当第一次进入while循环,执行str.hastNext(),
之后,cursor=1,list.remove(s)一个元素后 size=1;
public boolean hasNext() {
    return cursor != size;
}
由这个方法判断条件
cursor!=size,(其实集合里面还是有元素的哈),条件不满足就不会执行while循环里面的语句了。。所以就理所当然不会报
java.util.ConcurrentModificationException,真是醉了。。。。。。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值