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


当前回答

使用薄包装:HMap

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

public class HMap<K, V> {

   private final Map<K, Map<K, V>> map;

   public HMap() {
      map = new HashMap<K, Map<K, V>>();
   }

   public HMap(final int initialCapacity) {
      map = new HashMap<K, Map<K, V>>(initialCapacity);
   }

   public boolean containsKey(final Object key) {
      return map.containsKey(key);
   }

   public V get(final Object key) {
      final Map<K, V> entry = map.get(key);
      if (entry != null)
         return entry.values().iterator().next();
      return null;
   }

   public K getKey(final Object key) {
      final Map<K, V> entry = map.get(key);
      if (entry != null)
         return entry.keySet().iterator().next();
      return null;
   }

   public V put(final K key, final V value) {
      final Map<K, V> entry = map
            .put(key, Collections.singletonMap(key, value));
      if (entry != null)
         return entry.values().iterator().next();
      return null;
   }
}

其他回答

对于针对API < 19的Android开发,Vitalii Fedorenko一对一关系解决方案无法工作,因为对象。Equals没有实现。这里有一个简单的替代方案:

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

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

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

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

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

Map<Value, Set<Key>>

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

我认为你的选择是

Use a map implementation built for this, like the BiMap from google collections. Note that the google collections BiMap requires uniqueless of values, as well as keys, but it provides high performance in both directions performance Manually maintain two maps - one for key -> value, and another map for value -> key Iterate through the entrySet() and to find the keys which match the value. This is the slowest method, since it requires iterating through the entire collection, while the other two methods don't require that.

据我所知,当你将HashMap的键和值表示为数组时,它们是不混合的:

hashmap.values().toArray()

and

hashmap.keySet().toArray()

所以下面的代码(从java 8开始)应该像预期的那样工作:

public Object getKeyByFirstValue(Object value) {
    int keyNumber =  Arrays.asList(hashmap.values().toArray()).indexOf(value);
    return hashmap.keySet().toArray()[keyNumber];
}

然而,(警告!)它的工作速度比迭代慢2-3倍。