【问题标题】:Remove a key in hashmap when the value's hashset is Empty当值的哈希集为空时删除哈希图中的键
【发布时间】:2013-03-30 03:13:24
【问题描述】:

我有一个将字符串键映射到散列集值的散列图,当散列图的散列集值为空时,我想从散列图中删除一个键。我很难解决这个问题。这是我尝试过的,但我很卡住:

for(Map.Entry<String, HashSet<Integer>> entr : stringIDMap.entrySet()) 
{  

                String key = entr.getKey();  

                if (stringIDMap.get(key).isEmpty())
                {

                    stringIDMap.remove(key);
                    continue;
                }
     //few print statements...
}

【问题讨论】:

  • hashmap 中的值,即 HashSet 对于某些字符串可以为空吗?您现在面临什么问题?获取 NullPointer?

标签: java hashmap set hashset


【解决方案1】:

为了避免ConcurrentModificationException,需要直接使用Iterator接口:

Iterator<Map.Entry<String, HashSet<Integer>>> it = stringIDMap.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry<String, HashSet<Integer>> e = it.next();
    String key = e.getKey();
    HashSet<Integer> value = e.getValue();
    if (value.isEmpty()) {
        it.remove();
    }
}

您当前的代码不起作用的原因是您试图在迭代地图时从地图中删除元素。当您调用 stringIDMap.remove() 时,这会使 for-each 循环在后台使用的迭代器无效,从而无法进行进一步的迭代。

it.remove() 解决了这个问题,因为它不会使迭代器失效。

【讨论】:

    【解决方案2】:
     Iterator<String> iterator = mMapFiles.keySet().iterator();
        while (iterator.hasNext()){
            if ( mMapFiles.get( iterator.next() ).size() < 1 )
                iterator.remove();
        }
    

    【讨论】:

      【解决方案3】:

      从 Java 8 开始,有一个非常棒的 lambda 短解决方案:

      stringIDMap.entrySet().removeIf(ent -> ent.getValue().isEmpty());
      

      或者你可以通过传递方法引用来使用更简洁的方式

      stringIDMap.values().removeIf(Set::isEmpty);

      【讨论】:

      • 更好的选项 stringIDMap.values().removeIf(Set::isEmpty);
      • 是的,它更短,谢谢!将添加到我的答案中以提高知名度。
      猜你喜欢
      • 2013-10-09
      • 2016-02-06
      • 2021-12-15
      • 2011-07-01
      • 2023-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多