【问题标题】:HashMap delete entry AND positionHashMap 删除条目和位置
【发布时间】:2014-08-22 07:27:41
【问题描述】:

我只是在与HashMaps 合作,现在它会弹出一个我自己无法回答的问题...

在我的 HashMap 中有一些条目。我现在正在所有条目中搜索某个值。如果找到该值,则使用hashmap.remove(); 将其删除。但我不是“只”要删除条目,而是要删除 HashMap 的整个“位置”,以便它之间没有空格。最后 HashMap 不应该再有任何价值了(我认为它会是空的,不是吗?)

有没有办法做到这一点?

这就是我到目前为止所得到的,但它只会删除条目而不是整个位置......

for (Entry<Integer, String> entry : myMap.entrySet()) {
    if (entry.getValue().contains("EnterStringHere")) {
        myMap.remove(entry);
    }
}

【问题讨论】:

  • 向我们展示您的代码,尤其是在所有条目中搜索某个值的部分。
  • 你能分享你现有的代码吗?
  • 我不确定我是否理解这个问题。您是否希望 HashMap 在删除条目时使用更少的存储桶?你为什么在乎?
  • ... 为什么要让 hashmap 变短?
  • 定义“删除职位”的含义。会发生什么,而您希望发生什么? HashMaps 没有“位置”,所以很难理解你的意思。此外,您的代码将导致 ConcurrentModificationException。使用迭代器删除条目。

标签: java hashmap


【解决方案1】:

这是错误的

for (Entry<Integer, String> entry : myMap.entrySet()) {
if (entry.getValue().contains("EnterStringHere")) {
    myMap.remove(entry); // you should pass the key to remove
   }
 }

但是你不能用这种方式来移除元素。你会得到ConcurrentModificationException

您可以尝试使用iterator 在迭代时删除元素。

 Map<Integer,String> map=new HashMap<>();
 map.put(1,"EnterStringHere");
 map.put(2,"hi");
 map.put(3,"EnterStringHere");
 Iterator<Map.Entry<Integer,String>> iterator=map.entrySet().iterator();
 while (iterator.hasNext()){
    Map.Entry<Integer,String> entry=iterator.next();
        if(entry.getValue().equals("EnterStringHere")){
            iterator.remove();
        }
    }
 System.out.println(map);

输出:

 {2=hi}

你真的需要看看HashMap#remove()

【讨论】:

    【解决方案2】:

    您不能从地图中删除条目对象。 remove 方法需要密钥。

    您可以尝试以下方法:-

    Iterator<Entry<Integer, String>> itr = myMap.entrySet().iterator();
    
            while(itr.hasNext()) {
                Entry<Integer, String> entry = itr.next();
                if (entry.getValue().contains("EnterStringHere")) 
                { 
                    itr.remove(); 
                }
            }
    

    此外,您不能在迭代时直接在结构上修改 Map,否则您将收到 ConcurrentModification 异常。为了防止这种情况,您需要使用迭代器上的 remove 方法删除,如上面的代码所示。

    【讨论】:

      【解决方案3】:

      假设您的Map&lt;Key,Value&gt; 大小为10,并且您想删除当前Map 中的8th 键值对。发生的情况是Map 变成9 的大小并且在8th 位置会有另一个键值对。

      remove() 无法超越。您无法删除该职位。

      但是当您使用Map.get(removed_key) 时,您将得到null,因为现在那里没有密钥。

      例如:

      Map<String,Integer> map=new HashMap<>();
      map.put("a",1);
      map.put("b",2);
      map.put("c", 3);
      System.out.println("size of the map "+map.size() +" map is "+map);
      map.remove("b");
      System.out.println("size of the map "+map.size() +" map is "+map);
      System.out.println(map.get("b"));
      

      输出:

      size of the map 3 map is {b=2, c=3, a=1}
      size of the map 2 map is {c=3, a=1}
      null // you are getting null since there is no key "b"
      

      添加这个来回答你的评论,如果你想检查地图是否为空。只需使用map.isEmpty()

      【讨论】:

        【解决方案4】:

        了解HashMap 在此处Link 的工作原理。 另请参阅此处的 java 文档link

        如果你想设置你的 hashmap 包尝试检查地图的大小然后删除一个然后再次检查大小。

        hashmap.size();        => 10
        hashmap.remove(obj);
        hashmap.size()         => 9
        

        这意味着 hashmap 被打包并且不会有任何空条目。最后 hashmap 将自动不包含任何值

        【讨论】:

          【解决方案5】:

          因为在一定时间后我需要检查 HashMap 是否为空。但另一个答案似乎得到了我需要的提示。如果我删除该值,该条目将为空?我可以检查每个条目是否很容易为空,还是必须再次遍历每个条目?

          您没有从 Map 中删除值,而是删除了映射。这段代码不会删除任何东西:

          myMap.remove(entry);
          

          因为你传递了入口对象,所以你需要传递映射的键才能删除它,见Map.html#remove docs。

          因此

          myMap.remove(entry.getkey());
          

          但是,使用当前方法,您将在 ConcurrentModificationException 中运行。如果到现在还没有,那只是因为你的代码没有删除任何东西,因为你传递了入口对象

          如果您从地图中删除映射,则该映射将不再存在于地图中。存储桶是否为null 是实现细节,但是当您查询使用给定键删除的映射时,您将get null 作为返回值。如果您使用相同的键添加另一个映射,您将再次获得 taht 映射。

          您可以使用Map#isEmpty 检查地图是否为空,因此您无需检查每个条目是否为空或遍历整个地图。

          您可以使用Map.#containsKey检查映射是否包含键的映射

          您可以使用Map#containsValue检查一个映射是否包含至少一个值的映射

          在迭代它以使用iterator时从地图中删除etriey的正确方法

          Iterator<Entry<Integer, String>> iterator = myMap.entrySet().iterator();
          while(iterator.hasNext()) {
              Entry<Integer, String> entry = iterator.next();
              if (entry.getValue().contains("foo")) {
                  iterator.remove();
              }
          }
          

          既然你有Map&lt;Integer, String&gt;,我假设你的意思是位置 是整数键,你可以在其中执行myMap.put(1, ".")myMap.put(2, "..")myMap.put(3, "...") 等操作。在这种情况下,如果您删除键 1 的映射,则位置,即映射 {1 : "."} 将不再存在于映射中。

          【讨论】:

            【解决方案6】:

            好的,我有一个非常简单的可编码示例。

            public class TestingThingsOut {
            
            public static void main(String [] args) {
                HashMap<Integer, String> myMap = new HashMap<Integer, String>();
            
                myMap.put(123, "hello");
                myMap.put(234, "Bye");
                myMap.put(789, "asdf");
            
                System.out.println(myMap); // it says:
                                              {789=asdf, 234=Bye, 123=hello}
            
                System.out.println(myMap.size()); // it says: "3"
            
                for (Entry<Integer, String> entry : myMap.entrySet()) {
                    if (entry.getValue().contains("hello")) {
                        myMap.remove(entry);
                    }
                }
            
                System.out.println(myMap); // it says:
                                              {789=asdf, 234=Bye, 123=hello}
            
                System.out.println(myMap.size()); // it says: "3" again
            }
            

            }

            【讨论】:

            • 您不能使用 for-each 删除元素。您将获得 ConcurrentModificationException。你在这里做错了
            • @Shijury 此解决方案也不会删除该元素。请在下面查看我的答案
            • 在这段代码中什么也没有发生。如果你想从Map 中删除元素。你应该打电话给map.remove(key)。克莱尔完全阅读了我的两个答案
            • 您应该迭代 keySet 而不是 entrySet 以获得异常
            • 这不是这个问题的答案。您可以编辑您的问题以提供您尝试过的内容。
            猜你喜欢
            • 2017-03-30
            • 2015-05-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-09-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多