Java映射,从值到键

时间:2011-04-14 22:21:12

标签: java maps

有没有办法获得与地图中已知值相关联的键?通常你知道密钥并且你想获得值,但我想做相反的事情,从值到密钥。可能吗?

5 个答案:

答案 0 :(得分:2)

是的,您必须遍历地图中的值,然后将每个键存储在列表中:

for (Map.Entry<K,V> entry : map.entrySet()) {
  V value = entry.getValue();
  if (value.equals(someTargetValue) {
      // add key (entry.getKey()) to list
  }
}

或者您可以使用bidirectional map,但请注意:

  

此映射强制执行键和值之间存在1:1关系的限制,这意味着多个键无法映射到相同的值。

答案 1 :(得分:1)

好吧,我不是Google Project LambdaJ的专家,但它确实提供了一些很酷的选择。

假设您有一张包含该月所有日期的地图:

month.put(1,"Monday");
month.put(2,"Tuesday");
month.put(3,"Wednesday");
...

然后我们可以很容易地实现你想要的东西:

Set<Integer> result = with(month).retainValues(is("Friday")).keySet();

甚至还有一些有趣的搜索:

Set<Integer> result = with(month).retainValues(anyOf(is("Monday"),is("Friday"))).keySet();

答案 2 :(得分:0)

如果不迭代所有寻找值的键,您可以使用Apache Commons BidiMap

答案 3 :(得分:0)

Map是一个数学条目,并不意味着可以进行反向映射。也就是说,如果每个映射值都是唯一的,您可以创建一个“反向”映射。当然,您必须将所有数据操作封装在适当更新两个映射的方法中。

Map<Key, Value> normal;
Map<Value, Key> reverse;

如果每个映射值都不唯一,那么您需要创建一个值到一个键列表的反向映射。

Map<Key, Value> normal;
Map<Value, List<Key>> reverse;

最后,如果您不关心快速访问,则可以遍历整个Map查找值。由于您需要Value和Key,因此最好迭代Map.Entry项。

Value searchingFor = ...;
Map<Key, Value> normal;
List<Key> keys = new ArrayList<Key>();
for (Map.Entry<Key, Value> entry : normal.entrySet()) {
   if (entry.getValue().equals(searchingFor)) {
     keys.add(entry.getKey());
   }
}

您选择使用的技术在很大程度上取决于交换内存占用速度是否更好。由于在值上进行散列,通常有额外的Map更快,但需要额外的内存。在Map.Entry上循环较慢,但内存成本较低。

答案 4 :(得分:0)

他们已经在这里讨论过双向地图。如今,Guava(https://github.com/google/guava)提供了一个很好的BiMap,可以用于此目的:

https://github.com/google/guava/wiki/NewCollectionTypesExplained#bimap