迭代时从列表中删除项目

时间:2014-09-01 23:23:30

标签: java list concurrency iterator

在遍历列表时,可能会删除项目。

private void removeMethod(Object remObj){
    Iterator<?> it = list.iterator();
    while (it.hasNext()) {
        Object curObj= it.next();
        if (curObj == remObj) {
            it.remove();
            break;
        }
    }
}

当上述代码发生在另一个循环中时,会出现问题,这个循环正在主动迭代原始列表。

private void performChecks(){
    for(Object obj : list){
        //perform series of checks, which could result in removeMethod 
        //being called on a different object in the list, not the current one
    }
}

如何在遍历时从列表中删除未知对象?

实施例

我有一个监听器对象列表。在通知听众一个事件时,可能不再需要其他听众。

2 个答案:

答案 0 :(得分:0)

如果我理解你的问题,以下将是可能的解决方案(可能不是最有效但我认为值得一试):

在performChecks()下使用for(Object obj : list.toArray())

优点:每次将列表“刷新”到数组时,它都会反映更改。  因此,如果项目在单独的循环中从列表中删除

答案 1 :(得分:0)

你的问题有点令人困惑所以我会回答我的理解;您的问题是:在同时迭代列表并删除项目时如何从列表中删除项目或如何避免ConcurrentModificationException

首先,代码中的问题是您使用迭代器而不是列表删除项目。其次,如果您使用的是并发,请使用CopyOnWriteArrayList并使用

删除该项
  

list.remove()

为方案提供一个很好的示例,请检查this

所以这不好:

List<String> myList = new ArrayList<String>();

    myList.add("1");
    myList.add("2");
    myList.add("3");
    myList.add("4");
    myList.add("5");

    Iterator<String> it = myList.iterator();
    while(it.hasNext()){
        String value = it.next();
        System.out.println("List Value:"+value);
        if(value.equals("3")) myList.remove(value);
    }

这很好:

List<String> myList = new CopyOnWriteArrayList<String>();

    myList.add("1");
    myList.add("2");
    myList.add("3");
    myList.add("4");
    myList.add("5");

    Iterator<String> it = myList.iterator();
    while(it.hasNext()){
        String value = it.next();
        System.out.println("List Value:"+value);
        if(value.equals("3")){
            myList.remove("4");
            myList.add("6");
            myList.add("7");
        }
    }
    System.out.println("List Size:"+myList.size());