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


当前回答

使用Java 8:

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

其他回答

听起来最好的方法是使用map.entrySet()来遍历条目,因为map.containsValue()可能会这样做。

如果你的数据结构在键和值之间有多对一映射,你应该遍历条目并选择所有合适的键:

public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
    Set<T> keys = new HashSet<T>();
    for (Entry<T, E> entry : map.entrySet()) {
        if (Objects.equals(value, entry.getValue())) {
            keys.add(entry.getKey());
        }
    }
    return keys;
}

如果是一对一的关系,你可以返回第一个匹配的键:

public static <T, E> T getKeyByValue(Map<T, E> map, E value) {
    for (Entry<T, E> entry : map.entrySet()) {
        if (Objects.equals(value, entry.getValue())) {
            return entry.getKey();
        }
    }
    return null;
}

在Java 8中:

public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
    return map.entrySet()
              .stream()
              .filter(entry -> Objects.equals(entry.getValue(), value))
              .map(Map.Entry::getKey)
              .collect(Collectors.toSet());
}

此外,对于番石榴用户来说,BiMap可能也很有用。例如:

BiMap<Token, Character> tokenToChar = 
    ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);

你也可以这样做: 第一个:put map (key, value) 第二:更新键需要删除表达式 第三:和oldValue一起放一个新键

用你自己的实现来装饰地图

class MyMap<K,V> extends HashMap<K, V>{

    Map<V,K> reverseMap = new HashMap<V,K>();

    @Override
    public V put(K key, V value) {
        // TODO Auto-generated method stub
        reverseMap.put(value, key);
        return super.put(key, value);
    }

    public K getKey(V value){
        return reverseMap.get(value);
    }
}

让我们看看我的例子

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"]

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