18

我需要检查地图是否包含列表中的任何键,如果包含则返回第一个匹配值。想到的幼稚方法是在两个嵌套循环中执行此操作:

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 标准库?

4

9 回答 9

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

如果 null 值可能在 map 中,并且只需要第一个检测到的键,这是最好的方法。

于 2012-12-28T11:04:34.870 回答
24

肯定是这样的:

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

以上仅对每个候选键执行一次映射查找。它避免了存在和提取的单独测试,因为提取不存在的键只会给你一个空值。请注意(感谢Slanec),对于此解决方案,有效密钥的空值与不存在的密钥无法区分。

顺便说一句,我不太明白您为什么要执行大小写转换。

于 2012-12-28T11:05:07.257 回答
18

在 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 回答

于 2017-01-19T13:43:27.777 回答
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);
    }
}
于 2012-12-28T11:04:45.957 回答
7

在 Java 8 中,您可以使用它:

return candidates.stream()
            .filter(fields::containsKey)
            .findFirst()
            .map(fields::get)
            .orElse(null);
于 2016-11-18T09:35:07.887 回答
5

尝试

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

所以keySet应该有列表中提到的 HashMap 中的所有键

于 2012-12-28T11:09:39.263 回答
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
于 2012-12-28T11:06:51.087 回答
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);
}

}
于 2012-12-28T11:05:17.820 回答
1

如果您假设映射的键已经是小写,则可以使用单个循环,就像您假设查找值是小写一样。

于 2012-12-28T11:10:52.803 回答