代码之家  ›  专栏  ›  技术社区  ›  Hristo

如何在Java中修改对象时对其进行迭代?[副本]

  •  5
  • Hristo  · 技术社区  · 15 年前


    Java: Efficient Equivalent to Removing while Iterating a Collection
    Removing items from a collection in java while iterating over it

    我正试着绕过去 HashMap :

    Map<String, Integer> group0 = new HashMap<String, Integer>();
    

    group0

    // iterate through all Members in group 0 that have not been assigned yet
    for (Map.Entry<String, Integer> entry : group0.entrySet()) {
    
        // determine where to assign 'entry'
        iEntryGroup = hasBeenAccusedByGroup(entry.getKey());
        if (iEntryGroup == 1) {
            assign(entry.getKey(), entry.getValue(), 2);
        } else {
            assign(entry.getKey(), entry.getValue(), 1);
        }
    }
    

    这里的问题是 assign() 将从中删除元素 组0

    Exception in thread "main" java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:793)
        at java.util.HashMap$EntryIterator.next(HashMap.java:834)
        at java.util.HashMap$EntryIterator.next(HashMap.java:832)
        at liarliar$Bipartite.bipartition(liarliar.java:463)
        at liarliar$Bipartite.readFile(liarliar.java:216)
        at liarliar.main(liarliar.java:483)
    

    组0

    6 回复  |  直到 8 年前
        1
  •  7
  •   Sean Patrick Floyd    15 年前

    其他人提到了正确的解决办法,但实际上并没有说清楚。所以这里是:

    Iterator<Map.Entry<String, Integer>> iterator = 
        group0.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry<String, Integer> entry = iterator.next();
    
        // determine where to assign 'entry'
        iEntryGroup = hasBeenAccusedByGroup(entry.getKey());
    
        if (iEntryGroup == 1) {
            assign(entry.getKey(), entry.getValue(), 2);
        } else {
            assign(entry.getKey(), entry.getValue(), 1);
        }
    
        // I don't know under which conditions you want to remove the entry
        // but here's how you do it
        iterator.remove();
    }
    

    另外,如果要安全地更改assign函数中的映射,则需要传入迭代器(其中只能使用remove函数并且只能使用一次)或条目来更改值。

        4
  •  1
  •   CurtainDog    15 年前

    在您的特定情况下,我不会修改HashMap的结构,而只是将要删除的值设为null。如果最后访问的是空值,请跳过它。

        5
  •  0
  •   Affe    15 年前

    如果要在循环遍历集合时修改集合,则需要使用实际的迭代器及其remove方法。实际上没有任何方法可以使用foreach构造。

    Set<String> keys = new HashSet<String>(group0.keySet());
    for (String key : keys) {
      if (group0.containsKey(key)) {
        Integer value = group0.get(key);
        //your stuff 
      }
    }
    
        6
  •  0
  •   fastcodejava    15 年前

    在这种情况下,你怎么能 assign group0 ? 需要更多的细节。通常,在对集合进行迭代时不能对其进行修改。您可以通过 Iterator 接口。