2012-12-28 73 views
6

我需要檢查map是否包含列表中的任何鍵,如果它包含,則返回第一個匹配值。我想到的簡易方法是做兩個嵌套的循環:查找映射是否包含列表中的任何鍵的有效方法

Map<String, String> fields = new HashMap<String, String>(); 
fields.put("a", "value a"); 
fields.put("z", "value z"); 
String[] candidates = "a|b|c|d".split("|"); 
for (String key : fields.keySet()){ 
    for (String candidate : candidates) { 
     if (key.equals(candidate)){ 
      return fields.get(key); 
     } 
    } 
} 

是否有更好和更有效的方式,可能是一個依賴於Java標準庫?

回答

19

當然是這樣的:

for (String candidate : candidates) { 
    String result = fields.get(key); 
    if (result != null) { 
     return result; 
    } 
} 

以上僅執行每個候選鍵一個地圖查找。它避免了存在和提取的單獨測試,因爲提取一個不存在的鍵只會給你一個空值。請注意(感謝Slanec)有效密鑰的空值與此解決方案的不存在密鑰不可區分。

我不明白你爲什麼要執行案例轉換,順便說一句。

+8

這是有效的,因爲它可以得到的,但是如果'null'是'Map'中的允許值,它可能會變得棘手。 –

+3

有趣...我的理解是否正確,只是使用'map。get()'一次而不是'map.contains()+ map.get()',因爲這會避免第二次查找?那很整齊! – ccpizza

+3

@NimChimpsky retainAll是descructive。 –

20
for(String candidate : candidates) { 
if(fields.containsKey(candidate)) { 
    return fields.get(candidate) 
} 
} 

如果空值可能在映射中,並且只需要第一個檢測到的密鑰,那麼這是最好的方法。

7

我的看法:

Map<String, String> fields = new HashMap<String, String>(); 
fields.put("a", "value a"); 
fields.put("z", "value z"); 
String[] candidates = "a|b|c|d".split("|"); 
for (String candidate : candidates) { 
    if (fields.containsKey(candidate)) { 
     return fields.get(candidate); 
    } 
} 
1
Map<String, String> fields = new HashMap<String, String>(); 
fields.put("a", "value a"); 
fields.put("z", "value z"); 
String[] candidates = "a|b|c|d".split("|"); 
List<String> canList = Arrays.asList(candidates); 
for (String key : fields.keySet()){ 

if (canList .contains(key)) { 
return fields.get(key); 
} 

} 
+1

**注**:canList.contains在時間上是線性的。 – Srinivas

2

嘗試爲

List list= Arrays.asList(1, 2, 3); 
    HashMap map = new HashMap(); 
    map.put(1, 1); 
    map.put(3, 3); 
    Set set = new HashSet(map.keySet()); 
    set.retainAll(list); 
    System.out.println(set); 
    Object e = set.isEmpty() ? null : set.iterator().next(); 
    System.out.println(e); 

輸出

[1, 3] 
1 
5

嘗試

Set<String> keySet = new HashSet<String>(fields.keySet());  
keySet.retainAll(list); 

所以keySet應該具有的HashMap它們在列表中提及的所有鍵

+2

這是,我相信,最短的路。然而,它可能不是最快的,因爲循環在第一個結果結束時結束,但是這繼續其工作直到結束。 –

+3

@Slanec,是的,它取決於OP是否想要獲得所有密鑰或只是第一個。 –

1

如果您假定地圖的鍵已經是小寫字母,則可以使用單個循環,這與您假設查詢值採用小寫字母的方式相同。

4

在Java 8,你可以使用這個:

return candidates.stream() 
      .filter(fields::containsKey) 
      .findFirst() 
      .map(fields::get) 
      .orElse(null); 
5

在Java 8,你可以有這樣的:

boolean exists = Arrays.stream(candidates).anyMatch(fields::containsKey); 

如果你只是想知道,如果任何候選人的關鍵是地圖。

如果你想知道的第一或任何你可以使用:

Arrays.stream(candidates).filter(fields::containsKey).findAny(); 

Arrays.stream(candidates).filter(fields::containsKey).findFirst(); 

按@ Klapsa2503回答上述

相關問題