过滤,如果需要遍历集合,然后删除选定元素,此时只能使用显示的迭代器,以便可以调用remove方法,而不能使用foreach循环.
案例如下:
import java.util.ArrayList;
import java.util.List;
public class Fruit {
private String name;
private String type;
private String address;
public Fruit() {
}
public Fruit(String name, String type, String address) {
this.name = name;
this.type = type;
this.address = address;
}
//get和set方法
public static void main(String[] args) {
List<Fruit> fruits = new ArrayList<Fruit>();
Fruit fruit = null;
for (int i = 0; i < 10; i++) {
fruit = new Fruit("fruitName"+i, "fruitType"+i, "fruitAddress"+i);
fruits.add(fruit);
}
for (Fruit vfruit : fruits) {
if (vfruit.getName().contains("5")){
fruits.remove(vfruit);
}
}
System.err.println(fruits.size());//关注的焦点
}
}
主要查看上面输出语句,预期的个数是9个,因为删除掉1个.实际上,报错ConcurrentModificationException
public class ConcurrentModificationException extends RuntimeException
当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。
例如,某个线程在 Collection 上进行迭代时,通常不允许另一个线性修改该 Collection。通常在这些情况下,迭代的结果是不确定的。如果检测到这种行为,一些迭代器实现(包括 JRE 提供的所有通用collection 实现)可能选择抛出此异常。执行该操作的迭代器称为快速失败迭代器,因为迭代器很快就完全失败,而不会冒着在将来某个时间任意发生不确定行为的风险。
所以foreach是不能用在过滤删除数据上面的!
如何过滤删除呢,使用迭代器进行过滤删除.
Fruit delfruit = null;
for (Iterator<Fruit> iterator = fruits.listIterator(); iterator.hasNext();) {
delfruit = iterator.next();
if (delfruit.getName().contains("5")){
iterator.remove();
}
}
System.err.println(fruits.size());//结果是9,表示删除成功