如果我有值“foo”,和一个HashMap<String> ftw,其中ftw. containsvalue(“foo”)返回真,我怎么能得到相应的键?我需要遍历hashmap吗?最好的方法是什么?


当前回答

public class NewClass1 {

    public static void main(String[] args) {
       Map<Integer, String> testMap = new HashMap<Integer, String>();
        testMap.put(10, "a");
        testMap.put(20, "b");
        testMap.put(30, "c");
        testMap.put(40, "d");
        for (Entry<Integer, String> entry : testMap.entrySet()) {
            if (entry.getValue().equals("c")) {
                System.out.println(entry.getKey());
            }
        }
    }
}

一些额外的信息…可能对你有用

如果你的hashmap真的很大,上面的方法可能不太好。如果您的hashmap包含唯一键到唯一值的映射,您可以维护一个包含从值到键映射的hashmap。

也就是说你必须维护两个hashmap

1. Key to value

2. Value to key 

在这种情况下,您可以使用第二个hashmap来获取key。

其他回答

您可以将键、值对及其逆函数插入到映射结构中

map.put("theKey", "theValue");
map.put("theValue", "theKey");

使用map.get("theValue")将返回"theKey"。

这是一种快速而肮脏的方法,我已经创建了常量映射,它只适用于少数数据集:

只能包含1 ~ 1对 值集与键集不相交(1-> 2,2 ->3中断它)

没有明确的答案,因为多个键可以映射到相同的值。如果要在自己的代码中强制执行唯一性,最好的解决方案是创建一个类,该类使用两个hashmap在两个方向上跟踪映射。

在java8

map.entrySet().stream().filter(entry -> entry.getValue().equals(value))
    .forEach(entry -> System.out.println(entry.getKey()));

是的,您必须遍历hashmap,除非您按照这些不同答案所建议的方式实现某些东西。而不是摆弄entrySet,我只获得keySet(),遍历该集合,并保留为您提供匹配值的(第一个)键。如果你需要所有匹配这个值的键,显然你需要做所有的事情。

正如Jonas所建议的,这可能已经是containsValue方法正在做的事情,所以您可以完全跳过这个测试,而只是每次都进行迭代(或者编译器可能已经消除了冗余,谁知道呢)。

另外,相对于其他答案,如果你的反向映射看起来像

Map<Value, Set<Key>>

如果需要这种功能,您可以处理非唯一key->值映射(先解开它们)。这将把fine纳入人们建议的任何解决方案中,使用两张地图。

Lambda w/o使用外部库 一个键可以处理多个值(与BidiMap不同)

public static List<String> getKeysByValue(Map<String, String> map, String value) {
  List<String> list = map.keySet().stream()
      .collect(groupingBy(k -> map.get(k))).get(value);
  return (list == null ? Collections.emptyList() : list);
}

获取一个包含键映射值的列表 对于1:1映射,返回的列表为空或包含1个值