如果我有值“foo”,和一个HashMap<String> ftw,其中ftw. containsvalue(“foo”)返回真,我怎么能得到相应的键?我需要遍历hashmap吗?最好的方法是什么?
当前回答
需要注意的是,由于这个问题,Apache Collections支持通用的BidiMaps。因此,一些投票最多的答案在这一点上不再准确。
对于支持重复值(一对多场景)的Serialized BidiMap,也可以考虑MapDB.org。
其他回答
如果您选择使用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泛型。
对于针对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;
}
您可以将键、值对及其逆函数插入到映射结构中
map.put("theKey", "theValue");
map.put("theValue", "theKey");
使用map.get("theValue")将返回"theKey"。
这是一种快速而肮脏的方法,我已经创建了常量映射,它只适用于少数数据集:
只能包含1 ~ 1对 值集与键集不相交(1-> 2,2 ->3中断它)
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中获取给定值的键的最简单实用方法:
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(最终操作)来打印最终结果。
推荐文章
- 在流中使用Java 8 foreach循环移动到下一项
- 访问限制:'Application'类型不是API(必需库rt.jar的限制)
- 用Java计算两个日期之间的天数
- 如何配置slf4j-simple
- 在Jar文件中运行类
- 带参数的可运行?
- 我如何得到一个字符串的前n个字符而不检查大小或出界?
- 我可以在Java中设置enum起始值吗?
- Java中的回调函数
- c#和Java中的泛型有什么不同?和模板在c++ ?
- 在Java中,流相对于循环的优势是什么?
- Jersey在未找到InjectionManagerFactory时停止工作
- 在Java流是peek真的只是调试?
- Recyclerview不调用onCreateViewHolder
- 将JSON字符串转换为HashMap