2010-04-07 108 views
16

所以我有一個Java的HashMap象下面這樣:刪除一個給定值的所有項目從一個HashMap

hMap.put("1", "One"); 
hMap.put("2", "Two"); 
hMap.put("3", "Two"); 

我想刪除所有項目,其中值是「二」

如果我這樣做像這樣:

hmap.values().remove("Two"); 

只有第一個被刪除,我想全部刪除它們,這個怎麼辦?

回答

41

hmap.values().removeAll(Collections.singleton("Two"));

編輯:這種簡潔的方法的(顯著)缺點是,你基本上是被迫發表評論它,說像

// remove("Two") would only remove the first one

否則,有些苦口婆心工程師會盡量爲你簡化它,並打破它。發生這種情況......有時候,善意的做人甚至是未來你!

+0

這看起來不錯,有沒有什麼方法可以在上面寫一個調試行來告訴哪些鍵將被重擊? – 2010-04-07 18:59:21

+0

如果您需要記錄已刪除的密鑰,您可能需要查看Ron的解決方案(或我的,如果您願意添加google收藏)。 – 2010-04-07 19:32:21

+0

是的,如果你想知道你正在重擊的鑰匙,Ron和Jon的答案都是可行的。我傾向於喜歡羅恩,它只穿過地圖一次。 – 2010-04-08 05:07:22

13
for (Iterator<Map.Entry<String,String>> it = hMap.entrySet().iterator(); it.hasNext();) { 
Map.Entry<String,String> e = it.next(); 
if ("Two".equals(e.getValue())) { 
    it.remove(); 
} 
} 

+2

該解決方案肯定是有效的,但凱文的回答更加簡潔。 – 2010-04-07 18:25:39

+0

它可以放在一個單獨的方法中,如果它過於冗長,則無關緊要。 :P – 2014-03-14 15:08:47

2

你必須通過列表迭代,看值對象,並有條件地執行刪除。請注意,如果您在遍歷HashMap時嘗試刪除對象,則會發生異常。將不得不復制地圖或使用ConcurrentHashMap

10

如果集合因呼叫而改變,則可以使用while(hmap.values().remove("Two"));,因爲remove調用返回true

+0

這很有效,我認爲remove()返回布爾值的原因是很好的一部分。 – oedo 2010-04-07 16:30:31

+6

但是,這具有二次性能。 – 2010-04-07 17:02:30

+0

@kevin,什麼是「二次表演?」壞/好/? – 2010-04-07 18:44:58

6

(更新了去除值的記錄解決方案)

該解決方案使用了谷歌的集合庫[LINK]

import static com.google.common.collect.Maps.filterValues; 
import static com.google.common.base.Predicates.equalTo; 

... 

Map<String, String> removedValues = filterValues(hMap, equalTo("Two"));  
System.out.println(removedValues); //Log Removed Values 
removedValues.clear(); //Removes from original map, since this is a view. 

注意 - 該解決方案採用的事實,即由上圖返回filterValues調用是原始HashMap中元素的視圖。這允許我們檢查它們並註銷已刪除的密鑰,然後通過簡單地調用clear()將它們從原始映射中刪除。

您可能有不想在項目中使用google-collections庫的原因,但如果您不這樣做,我建議您檢查一下。

16

在Java 8

hmap.values().removeIf(val -> "Two".equals(val)); 
相關問題