有效地删除hashmap条目

时间:2013-08-21 16:24:02

标签: java hashmap

我必须比较2个Map个密钥,如果密钥基于map2'Y''N'相等,我必须从{{1}中删除该条目}。我在下面做,但得map1。你能告诉我为什么吗?

ConcurrentModificationException

3 个答案:

答案 0 :(得分:2)

你不能remove你正在迭代的Map元素。这会导致ConcurrentModificationException

在外部循环中迭代map2,并从map1中移除符合您条件的元素。

修改

这样做:

package stack.overflow.playground;

import java.util.HashMap;
import java.util.Map;

public class StackOverflowPlayground {

    public static void main(String[] args) {
        Map<String, String> map1 = new HashMap<>();
        map1.put("test", "1");
        map1.put("test2", "2");

        Map<String, String> map2 = new HashMap<>();
        map2.put("test", "Y");
        map2.put("test2", "N");

        for (Map.Entry<String, String> me : map2.entrySet()) {
            if ("Y".equals(me.getValue())) {
                map1.remove(me.getKey());
            }
        }

        System.out.println(map1); // {test2=2}
    }
}

答案 1 :(得分:1)

“增强的for循环”使用Iterator,在使用Iterator时修改集合的唯一安全方法是在迭代器上调用remove()。你可以这样做:

static void deleteFlaggedEntries(Map<?, ?> readwrite, Map<?, ?> readonly)
{
  Iterator<?> keys = readwrite.keySet().iterator();
  while (keys.hasNext()) {
    if ("Y".equals(readonly.get(keys.next())))
      keys.remove();
  }
}

请注意,通过将对equals()的调用反转,以便始终在字符串"Y"上调用它,您可以删除额外的检查以查看密钥是否与contains()一起显示,因为如果它丢失了,equals()来电将返回false而不是投放NullPointerException

答案 2 :(得分:0)

查看Map#entrySet()。此方法为您提供了地图条目集的实时视图,因此您可以使用Set#removeAll(otherSet)来实现设置差异。总而言之,它应该是一个单行:

map1.entrySet().removeAll(otherSet);

如果要将其与不同的数据库查询结合使用,而该数据库查询已只过滤了带有“Y”的行,则可以使用此功能。