arraylist等记录修改次数modCount有什么作用?

下面是源码中的注释,可以参考。

大概意思就是说:在使用迭代器遍历的时候,用来检查列表中的元素是否发生结构性变化(列表元素数量发生改变)了,主要在多线程环境下需要使用,防止一个线程正在迭代遍历,另一个线程修改了这个列表的结构。好好认识下这个异常:ConcurrentModificationException。对了,ArrayList是非线程安全的。

This field is used by the iterator and list iterator implementation returned by the iterator and listIterator methods. If the value of this field changes unexpectedly, the iterator (or list iterator) will throw a ConcurrentModificationException in response to the next, remove, previous, set or add operations. This provides fail-fast behavior, rather than non-deterministic behavior in the face of concurrent modification during iteration.

public class TestArrayListIterator {
    public static void main(String[] args)  {
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(10);
        Iterator<Integer> iterator = list.iterator();
        while(iterator.hasNext()){
            Integer integer = iterator.next();
            if(integer==10)
                list.remove(integer);   //注意这个地方
        }
    }
}

题主可以调试下上面的这个程序,会报运行时异常 ConcurrentModificationException
Exception in thread "main" java.util.ConcurrentModificationException
	at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
	at java.util.AbstractList$Itr.next(Unknown Source)
	at  com.notify.TestArrayListIterator.main(TestArrayListIterator.java:17)
在使用迭代器遍历的时候,如果使用ArrayList中的remove(int index) remove(Object o) remove(int fromIndex ,int toIndex) add等方法的时候都会修改modCount,在迭代的时候需要保持单线程的唯一操作,如果期间进行了插入或者删除,就会被迭代器检查获知,从而出现运行时异常

事实上在我们remove掉这个元素之后 ,该ArrayList的size()的值就变为了0,而此时Iterator的游标cursor是 1 ,在ArrayList迭代器的hasNext()方法中
public boolean hasNext() {
            return cursor != size();
	}
当中判断出cursor 确实不等于 size() 哭cry!!!!
然后循环又继续跑了!!!



如果我们不进行modCount和expectedModCount(创建迭代器的时候将当时的modCount赋值给expectedModCount),这个程序肯定会报ArrayIndexOutOfBoundsException,这样的异常显然不是应该出现的(这些运行时错误都是使用者的逻辑错误导致的,我们的JDK那么高端,不会出现使用错误,我们只抛出使用者造成的错误,而这个错误是设计者应该考虑的),为了避免出现这样的异常,定义了检查。


又想,为什么不把hasNext()的判断改为cursor <=size()呢?但是我们还有可能 add()这样的话就会导致数据混乱,事实上线程安全本身就不允许读的时候被修改





曾经在霸面大众点评时,面试官就出了一道题:

<span style="white-space:pre">		</span>ArrayList<String> list = new ArrayList<String>();
		for(int i =0;i<1000;i++){
			list.add("sh"+i);
		}

		for(int i= 0;list.iterator().hasNext();i++){
	<span style="white-space:pre">		</span>list.remove(i);
			System.out.println("秘密"+list.get(i));		
		}

Exception in thread "main" java.lang.IndexOutOfBoundsException: Index: 500, Size: 500
	at java.util.ArrayList.rangeCheck(ArrayList.java:635)
	at java.util.ArrayList.remove(ArrayList.java:474)
	at com.test.StringTest.main(StringTest.java:26)

会报什么错,当时仔细回忆分析了一下remove()的源码,但还是傻逼一样说报空指针错误。。。。。。。。。。。。。
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值