for-each的背后

如果想使用for-each来循环集合,那么这个集合就必须实现java.lang.Iterable这个接口;

首先在java的集合框架中java.util.Connection这个集合框架的根接口已经继承了前面的接口;

如果是我们自己编写的集合类,如果想要使用for-each的方式来循环遍历元素,那么就必须实现前面的接口,或者实现/继承已经实现过Iterable接口的接口或类。

否则在强行使用for-each的时候会抛出异常。

  • 所以关于for-each的第一要点是:被遍历的集合已经实现过java.lang.Iterable接口

然后是一个关于删除集合节点的问题:

这是准备数据:

Collection<String> list = new ArrayList<String>();
list.add("Android");
list.add("iPhone");
list.add("Windows Mobile");
首先是第一个例子eg1:
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
    String lang = itr.next();
    list.remove(lang);
    for(String lan : list){
        System.out.println(lan);
    }
}
输出:
iPhone
Windows Mobile
Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at com.test.list.ForEachTest2.main(ForEachTest2.java:17)
然后是第二个例子eg2:
Iterator<String> itr = list.iterator();
while (itr.hasNext()) {
	String lang = itr.next();
	itr.remove();
	System.out.println("---------------");
	for(String lan : list){
		System.out.println(lan);
	}
}
输出:
---------------
iPhone
Windows Mobile
---------------
Windows Mobile
---------------
eg1会抛出异常,但是eg2缺不会抛出异常;两个代码的区别就是删除节点所使用的方法不同:

eg1使用的是list本省自带的remove(object)方法

eg2使用的itr的remove()方法

报错的原因是因为在使用Iterator遍历集合的时候会检查元素的变化并抛出异常java.util.ConcurrentModificationException,即在使用该方式遍历集合的时候,集合元素的改变必须是Iterator对其进行的修改,这样才不会在接下来的遍历中发生错误,否则将会有异常发生。这就是为什么eg1会报错而eg2正常执行的原因。


接着要说的是,for-each的内部使用了Iterator来遍历集合,所以在使用for-each来执行上面eg1和eg2时,后有上面相同的错误发生。



详情请参考下面的文章

参考文章:Java for-each循环解惑

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值