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


当前回答

让我们看看我的例子

Map<String, String> mapPeopleAndCountry = new HashMap<>();
mapPeopleAndCountry.put("Matis", "Lithuania");
mapPeopleAndCountry.put("Carlos", "Honduras");
mapPeopleAndCountry.put("Teboho", "Lesotho");
mapPeopleAndCountry.put("Marielos", "Honduras");


List<String> peopleInHonduras = mapPeopleAndCountry.keySet()
    .stream()
    .filter(r -> mapPeopleAndCountry.get(r)
                .equals("Honduras"))
    .stream(Collectors.toList());

// will return ["Carlos", "Marielos"]

注:未经测试,可能含有错别字

其他回答

如果你在自己的代码中构建映射,尝试将map中的键和值放在一起:

public class KeyValue {
    public Object key;
    public Object value;
    public KeyValue(Object key, Object value) { ... }
}

map.put(key, new KeyValue(key, value));

当你有了一个值,你也就有了键。

如果您选择使用Commons Collections库而不是标准的Java Collections框架,则可以轻松实现这一点。

Collections库中的BidiMap接口是一个双向映射,允许您将一个键映射到一个值(像法线映射一样),也允许您将一个值映射到一个键,从而允许您在两个方向上执行查找。getKey()方法支持为值获取键。

但有一个警告,bidi映射不能有多个值映射到键,因此,除非您的数据集在键和值之间有1:1的映射,否则不能使用bidi映射。


如果您希望依赖Java Collections API,那么在将值插入映射时,必须确保键和值之间的1:1关系。说起来容易做起来难。

一旦您能够确保这一点,就可以使用entrySet()方法获取Map中的条目(映射)集。一旦您获得了类型为Map的集合。条目,遍历条目,将存储的值与预期的值进行比较,并获得相应的键。


对带泛型的bidi映射的支持可以在谷歌Guava和重构的Commons-Collections库中找到(后者不是Apache项目)。感谢Esko指出Apache Commons Collections中缺少的泛型支持。使用带有泛型的集合使代码更具可维护性。


从4.0版开始,官方Apache Commons Collections™库支持泛型。

请参阅“org.apache.commons.collections4.bidimap”包的摘要页,了解BidiMap、OrderedBidiMap和SortedBidiMap接口的可用实现列表,这些接口现在支持Java泛型。

使用Java 8:

ftw.forEach((key, value) -> {
    if (value.equals("foo")) {
        System.out.print(key);
    }
});

需要注意的是,由于这个问题,Apache Collections支持通用的BidiMaps。因此,一些投票最多的答案在这一点上不再准确。

对于支持重复值(一对多场景)的Serialized BidiMap,也可以考虑MapDB.org。

从Map中获取给定值的键的最简单实用方法:

public static void fetchValue(Map<String, Integer> map, Integer i)
{   
Stream stream = map.entrySet().stream().filter(val-> val.getValue().equals(i)).map(Map.Entry::getKey);
stream.forEach(System.out::println);    
}

详细解释:

方法fetchValue接受映射,该映射的键是String,值是Integer。 然后使用entryset().stream()将结果转换为流。 接下来,我们使用过滤器(中间操作),它会给我们一个等于第二个参数的值。 最后,我们使用forEach(最终操作)来打印最终结果。