【Java必修课】经由过程Value猎取Map中的键值Key的四种要领
2019-11-18杂谈搜奇网46°c
A+ A-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并不支撑多对一的关联。
怎样挑选,就看详细需求来弃取了。
迎接关注民众号<南瓜漫说>,将延续为你更新...
多读书,多分享;多写作,多整顿。