1 简介
我们都知道Map是存放键值对<Key,Value>的容器,知道了Key值,使用方法Map.get(key)能快速获取Value值。然而,有的时候我们需要反过来获取,知道Value值,求Key值。

本文将用实例介绍四种方法,通过传入Value值,获取得到Key值。

2 四种方法
2.1 循环法

循环法就是通过遍历Map里的Entry,一个个比较,把符合条件的找出来。会有三种情况:

(1)找到一个值

(2)找到多个值

(3)找不到

具体代码如下:

@Test
public void loop() {Map<String, Integer> map = ImmutableMap.of("A", 1, "B", 2, "C", 3, "D", 2);//找到一个值assertEquals("A", getKeyByLoop(map, 1));//找到多个值assertEquals(ImmutableSet.of("B", "D"), getKeysByLoop(map, 2));//找不到assertEquals(null, getKeyByLoop(map, 4));
}private <K, V> K getKeyByLoop(Map<K, V> map, V value) {for (Map.Entry<K, V> entry : map.entrySet()) {if (Objects.equals(entry.getValue(), value)) {return entry.getKey();}}return null;
}private <K, V> Set<K> getKeysByLoop(Map<K, V> map, V value) {Set<K> set = Sets.newHashSet();for (Map.Entry<K, V> entry : map.entrySet()) {if (Objects.equals(entry.getValue(), value)) {set.add(entry.getKey());}}return set;
}

想特别说的一点是,在对比是否相等的时候,使用了Objects.equals(a, b)方法,而不是用a.equals(b)方法。这样可以避免空指针异常。

2.2 Stream方法
Stream总是在多种集合操作上都能提供优雅直观的方法,易写易理解。通过一个过滤器,即可把满足相等条件的值取出来,代码如下:

@Test
public void stream() {Map<String, Integer> map = ImmutableMap.of("A", 1, "B", 2, "C", 3, "D", 2);assertEquals(ImmutableSet.of("B", "D"), getKeysByStream(map, 2));
}private <K, V> Set<K> getKeysByStream(Map<K, V> map, V value) {return map.entrySet().stream().filter(kvEntry -> Objects.equals(kvEntry.getValue(), value)).map(Map.Entry::getKey).collect(Collectors.toSet());
}

2.3 Guava的BiMap
Google的Guava提供了BiMap这样一个双向Map,调用inverse()方法会返回一个反向的关联的BiMap,然后便可以通过get()方法获取key值了。

代码如下:

@Test
public void guava() {BiMap<String, Integer> biMap = HashBiMap.create();biMap.put("A", 1);biMap.put("B", 2);biMap.put("C", null);biMap.put("D", 4);assertEquals("D", biMap.inverse().get(4));
}

需要注意的是,BiMap作为一个双向的Map,它不能存储多对一的关系;而HashMap是可以的。其实很好理解,因为是双向的,所以即要满足Key值的唯一性,也要满足Value值的唯一性。如果往里存放同样的Value,会抛异常:java.lang.IllegalArgumentException: value already present。

2.4 Apache Commons Collections的BidiMap
类似地,Apache Commons Collections也提供了双向Map的类BidiMap,它也是维持一对一的关系,不能多对一。它提供了getKey(value)方法返回Key值。代码如下:

@Test
public void apacheCommons() {BidiMap<String, Integer> bidiMap = new DualHashBidiMap<>();bidiMap.put("A", 1);bidiMap.put("B", 2);bidiMap.put("C", null);bidiMap.put("D", 4);assertEquals("D", bidiMap.getKey(4));
}

与Guava的BiMap不同的是,当存放同样的Value时,它不会抛异常,而是覆盖原有的数据。

3 总结
本文介绍了四种通过Value值获取Map中的Key值的方法,分别是循环法、Stream、Guava、Apache Commons Collections,这四种方法类似但不尽相同。

(1)循环法和使用Stram本质上都是要遍历的,如果一个Map经常需要反向取Key值,则不建议使用,可以考虑Guava和Apache Commons提供的双向Map;

(2)双向Map其实是一种空间换取时间的思想,虽然能较快的找到满足条件的Key值,但它也使用了更多的空间来储存双向Map;

(3)双向Map并不支持多对一的关系。

如何选择,就看具体需求来取舍了。

通过Value获取Map中的键值Key的四种方法相关推荐

  1. php 获取js对象的属性值,js获取对象,数组所有属性键值(key)和对应值(value)的方法示例...

    本文实例讲述了js获取对象,数组所有属性键值(key)和对应值(value)的方法.分享给大家供大家参考,具体如下: var values=function(object) { var values ...

  2. JS获取URL中参数值(QueryString)的4种方法分享

    http://www.jb51.net/article/48942.htm JS获取URL中参数值(QueryString)的4种方法分享 作者: 字体:[增加 减小] 类型:转载 今天碰到要在一个页 ...

  3. Linux系统中查看Mysql数据库版本号的四种方法(图文完整版)

    今天处理一个问题,发现要确定Mysql数据库的版本号,于是我就整理了一下我查看的几种方法. 第一种方法(在终端操作): 操作方式:在终端输入命令即可查询 命令:mysql -V 第二种方法(在终端操作 ...

  4. 移除map中的键值对

    背景 实现 A little bit of progress every dayCome on 背景 项目中需要移除map集合中对应的键值对,用以控制数据的变化. 实现 这里我写了一个测试方法,通过打 ...

  5. java如何获得键值_如何在java中取map中的键值 的两种方法

    第一种方法根据键值的名字取值 import java.util.HashMap; import java.util.Map; public class Test { /** * @param args ...

  6. JAVA中如何取map的值_如何在java中取map中的键值 的两种方法

    第一种方法根据键值的名字取值 import java.util.HashMap; import java.util.Map; public class Test { /** * @param args ...

  7. Mybatis 之 foreach 批处理 map 中的键值 为list 的操作

    foreach一共有三种类型,分别为List,[](array),Map三种. foreach的第一篇用来将List和数组(array). 下面表格是我总结的各个属性的用途和注意点. foreach属 ...

  8. Mac OS X 中快速访问系统根目录的四种方法

    就像其他Unix系统一样,Mac OS X的根目录也是/,Finder中的根目录就是硬盘目录,也就是Macintosh HD.新版本的OS X系统开始隐藏根目录,因为大多数用户不需要访问.下面为大家介 ...

  9. python中计算n次方运算的四种方法【转】

    https://blog.csdn.net/u011699626/article/details/119582754 这里介绍一下python中n次方运算的四种书写形式,代码如下: # -*- cod ...

最新文章

  1. ElasticSearch+聚合+Aggregation+示例
  2. 概率模型与条件随机场
  3. Pytorch学习 - Task6 PyTorch常见的损失函数和优化器使用
  4. 微服务启动报错命令行太长解决方案
  5. Copy List with Random Pointer
  6. codeforces:CF1604 总结
  7. python机械臂仿真_基于Python的3R机器人运动仿真
  8. win10家庭版无法安装mysql_大师处置win10系统家庭版安装MySQL server 5.7.19失败的详细办法...
  9. 安卓使用MediaPlayer自定义音频视频播放器
  10. 阿里云专家带你揭秘云计算数据底座——对象存储
  11. 第二阶段团队冲刺02
  12. 2015年数模A题太阳影子定位学习笔记
  13. 如何将NFC读卡器库移植到Kinetis K64F微控制器
  14. Android Studio 单独启动安卓模拟器教程
  15. 20组事后诸葛亮会议总结
  16. mysql表达式转字符串_[转载]MYSQL 字符串操作[]
  17. 各种RAID磁盘阵列组实际容量计算方法
  18. arduino点阵声音频谱_音频跳动:制造32分频音频频谱点阵
  19. 说出至少4种vue当中的指令和它的用法?
  20. MQTT学习之初识mqtt

热门文章

  1. ThinkPHP3.2的Excel导入
  2. 会玩,macOS 使用指纹解锁 sudo 密码
  3. Win10右下角任务栏网络图标消失不见,设置中通知区域网络开关是灰色的解决办法
  4. 深度好文-如何测试云硬盘
  5. 未将对象引用设置到对象的实例 问题原因总结
  6. 往日学习=【iptables实验part1】
  7. 分类变量、有序变量与数值变量相关性分析方法总结及 R 语言应用
  8. 你不知道的钣金加工工艺知识,简直不要太全面!
  9. 若个人计算机主板上的内存条松动,电脑内存条松动了怎么办?
  10. django:中间件