嗯,大部分都会遇到这个问题,定义一个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