您的位置:首页 > 编程语言 > Java开发

Java中使用foreach遍历list的盲点,

2018-03-29 11:35 211 查看
我们通常在项目中会用到ArrayList ,喜欢使用jdk1.5以后的foreach进行对list集合遍历,但是以下的操作会遇到小坑请看代码:public class TestListUtils {
public static void main(String[] args) {
ArrayList<Student> a = new ArrayList<Student>();
a.add(new Student(1, "zhao", true, 50.5, new Date()));
a.add(new Student(2, "qian", false, 60.5, new Date()));
a.add(new Student(3, "sun", true, 70.5, new Date()));
a.add(new Student(4, "li", false, 80.5, new Date()));
a.add(new Student(5, "zhou", true, 90.5, new Date()));
a.add(new Student(6, "wu", true, 1000.5, new Date()));
for (Student student : a) {
System.out.println(student);
}
System.out.println("=======================================");
ArrayList<Student> b = new ArrayList<Student>();
b.add(new Student(3, "sun", true, 70.5, new Date()));
b.add(new Student(4, "li", false, 80.5, new Date()));
b.add(new Student(5, "zhou", true, 90.5, new Date()));
for (Student student : b) {
System.out.println(student);
}
for (Student student : a) {
for (int i = 0; i < b.size(); i++) {
a.remove(i);
}
}
}
}
在代码中的双层循环中,我们都是使用foreach对list集合操作的,这样会报错,如下:
Student [id=1, name=zhao, sex=true, score=50.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=2, name=qian, sex=false, score=60.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=3, name=sun, sex=true, score=70.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=4, name=li, sex=false, score=80.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=5, name=zhou, sex=true, score=90.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=6, name=wu, sex=true, score=1000.5, birth=Thu Mar 29 11:05:31 CST 2018]
=======================================
Student [id=3, name=sun, sex=true, score=70.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=4, name=li, sex=false, score=80.5, birth=Thu Mar 29 11:05:31 CST 2018]
Student [id=5, name=zhou, sex=true, score=90.5, birth=Thu Mar 29 11:05:31 CST 2018]
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at test_cnbookingapi.TestListUtils.main(TestListUtils.java:36)
ArrayList的父类AbstarctList中有一个域
modCount
,每次对集合进行修改(增添元素,删除元素……)时都会
modCount++
而foreach的背后实现原理其实就是Iterator(关于Iterator可以看Java Design Pattern: Iterator),等同于注释部分代码。在这里,迭代ArrayList的Iterator中有一个变量
expectedModCount
,该变量会初始化和
modCount
相等,但如果接下来如果集合进行修改
modCount
改变,就会造成
expectedMod
9811
Count!=modCount
,此时就会抛出java.util.ConcurrentModificationException异常。
解决办法:
1)在使用iterator迭代的时候使用synchronized或者Lock进行同步;

2)使用并发容器CopyOnWriteArrayList代替ArrayList和Vector。不过我采用外层是for循环内层是foreach解决此问题:
public class TestListUtils {
public static void main(String[] args) {
ArrayList<Student> a = new ArrayList<Student>();
a.add(new Student(1,"zhao",true,50.5,new Date()));
a.add(new Student(2,"qian",false,60.5,new Date()));
a.add(new Student(3,"sun",true,70.5,new Date()));
a.add(new Student(4,"li",false,80.5,new Date()));
a.add(new Student(5,"zhou",true,90.5,new Date()));
a.add(new Student(6,"wu",true,1000.5,new Date()));
for (Student student : a) {
System.out.println(student);
}
System.out.println("=======================================");
ArrayList<Student> b= new ArrayList<Student>();
b.add(new Student(3,"sun",true,70.5,new Date()));
b.add(new Student(4,"li",false,80.5,new Date()));
b.add(new Student(5,"zhou",true,90.5,new Date()));
for (Student student : b) {
System.out.println(student);
}
//删除集a中的某个元素
/*for (Student student : a) {
for (int i = 0; i < b.size(); i++) {
a.remove(i);
}
}	*/
for (int i = 0; i < a.size(); i++) {
for (Student student : b) {
a.remove(i);
}
}
}
}

详细的讲解可以参考此文章:https://www.jianshu.com/p/c5b52927a61a
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐