聂永的博客

记录工作/学习的点点滴滴。

循环删除List数组容器里面元素

嗯,大部分都会遇到这个问题,定义一个List<T>数组,然后需要循环一下,删除其中一个元素,但会遇到类似问题:
java.util.ConcurrentModificationException
怎么办,实用主义者会把List数组转换成Iterator进行迭代删除,一点问题都没有:
 public static void main(String[] args) {
List<Student> students = pareStudents();

System.out.println("size : " + students.size());
System.out.println(students);

System.out.println("delete Student with name xiaoi");

Iterator<Student>stuIter = students.iterator();

while(stuIter.hasNext()){
Student stu = stuIter.next();
if(stu.getName().equals("xiaoi")){
stuIter.remove();
}
}

System.out.println("size : " + students.size());
System.out.println(students);
}

Iterator进行循环操作,然后删除,是很安全的。可以解决一些问题。但不要再使用Iterator的时候使用students.remove(stu),一样会给出 java.util.ConcurrentModificationException 错误。


另一个方法就是重新构建一个List,把原先的students 数组作为参数传递进去即可,虽然生成了一个全新的数组,但都是Student对象的引用,多个引用的地址数组而已。


 public static void main(String[] args) {
List<Student> students = pareStudents();

System.out.println("size : " + students.size());
System.out.println(students);

System.out.println("delete Student with name xiaoi");
for(Student s : new ArrayList<Student>(students)){
if(s.getName().equals("xiaoi")){
students.remove(s);
}
}

System.out.println("size : " + students.size());
System.out.println(students);
}


需要那一种方式,那就自便了,个人倾向于使用Iterator。
完整测试代码如下:

public class DeleteList {
private static class Student{
private String name;
private int age;

public Student(String name, int age) {
this.name = name;
this.age = age;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

public int hashCode() {
return name.hashCode();
}

public boolean equals(Object obj) {
if(obj == null || !(obj instanceof Student)){
return false;
}

Student objStu = (Student)obj;
return objStu.getName().equals(this.getName()) && objStu.getAge() == this.getAge();
}

public String toString(){
return name + " : " + age;
}
}

private static List<Student> pareStudents(){
ArrayList<Student> students = new ArrayList<Student>();

students.add(new Student("xiaoi", 18));
students.add(new Student("xiaoxin", 19));
students.add(new Student("john", 20));
students.add(new Student("xiaomei", 23));

return students;
}

public static void main(String[] args) {
List<Student> students = pareStudents();

System.out.println("size : " + students.size());
System.out.println(students);

System.out.println("delete Student with name xiaoi");
for(Student s : new ArrayList<Student>(students)){
if(s.getName().equals("xiaoi")){
students.remove(s);
}
}

System.out.println("size : " + students.size());
System.out.println(students);
}

public static void main2(String[] args) {
List<Student> students = pareStudents();

System.out.println("size : " + students.size());
System.out.println(students);

System.out.println("delete Student with name xiaoi");

Iterator<Student>stuIter = students.iterator();

while(stuIter.hasNext()){
Student stu = stuIter.next();
if(stu.getName().equals("xiaoi")){
stuIter.remove();
}
}

System.out.println("size : " + students.size());
System.out.println(students);
}
}

Iterator 是工作在一个独立的线程中,并且拥有一个 mutex 锁。 Iterator 被创建之后会建立一个指向原来对象的单链索引表,当原来的对象数量发生变化时,这个索引表的内容不会同步改变,所以当索引指针往后移动的时候就找不到要迭 代的对象,所以按照 fail-fast 原则 Iterator 会马上抛出 java.util.ConcurrentModificationException 异常。

所以 Iterator 在工作的时候是不允许被迭代的对象被改变的。但你可以使用 Iterator 本身的方法 remove() 来删除对象, Iterator.remove() 方法会在删除当前迭代对象的同时维护索引的一致性。

refer url : http://www.cnblogs.com/iloveu/archive/2009/06/23/1509385.html

posted on 2010-10-09 10:36 nieyong 阅读(4500) 评论(0)  编辑  收藏 所属分类: Java


只有注册用户登录后才能发表评论。


网站导航:
 

公告

所有文章皆为原创,若转载请标明出处,谢谢~

新浪微博,欢迎关注:

导航

<2010年10月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

统计

常用链接

留言簿(58)

随笔分类(130)

随笔档案(151)

个人收藏

最新随笔

搜索

最新评论

阅读排行榜

评论排行榜