Java Hashmap:如何从价值中获取关键?
如果我的值是"foo"
,并且ftw.containsValue("foo")
返回true
的HashMap<String> ftw
,如何获得相应的键? 我是否必须遍历哈希图? 最好的方法是什么?
#1楼
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;public class M{
public static void main(String[] args) {HashMap<String, List<String>> resultHashMap = new HashMap<String, List<String>>();Set<String> newKeyList = resultHashMap.keySet();for (Iterator<String> iterator = originalHashMap.keySet().iterator(); iterator.hasNext();) {String hashKey = (String) iterator.next();if (!newKeyList.contains(originalHashMap.get(hashKey))) {List<String> loArrayList = new ArrayList<String>();loArrayList.add(hashKey);resultHashMap.put(originalHashMap.get(hashKey), loArrayList);} else {List<String> loArrayList = resultHashMap.get(originalHashMap.get(hashKey));loArrayList.add(hashKey);resultHashMap.put(originalHashMap.get(hashKey), loArrayList);}}System.out.println("Original HashMap : " + originalHashMap);System.out.println("Result HashMap : " + resultHashMap);}
}
#2楼
没有明确的答案,因为多个键可以映射到相同的值。 如果要使用自己的代码强制唯一性,则最佳解决方案是创建一个使用两个Hashmap来跟踪两个方向上的映射的类。
#3楼
要查找映射到该值的所有键,请使用map.entrySet()
遍历哈希图中的所有对。
#4楼
听起来最好的方法是使用map.entrySet()
遍历条目,因为map.containsValue()
可能还是这样做。
#5楼
如果您选择使用Commons Collections库而不是标准Java Collections API,则可以轻松实现此目的。
Collections库中的BidiMap接口是双向映射,允许您将键映射到值(如法线映射),也可以将值映射到键,从而允许您在两个方向上执行查找。 getKey()方法支持获取值的键。
需要注意的是,bidi映射不能将多个值映射到键,因此,除非您的数据集在键和值之间具有1:1映射,否则您不能使用bidimaps。
更新资料
如果要依赖Java Collections API,则必须在将值插入映射时确保键和值之间的1:1关系。 说起来容易做起来难。
一旦可以确保使用,请使用entrySet()方法获取Map中的一组条目(映射)。 获得类型为Map.Entry的集合后,请遍历条目,将存储的值与期望值进行比较,并获得对应的key 。
更新#2
可以在Google Guava和重构的Commons-Collections库(后者不是Apache项目)中找到对带有泛型的比迪地图的支持。 感谢Esko指出Apache Commons Collections中缺少的通用支持。 将集合与泛型一起使用可使代码更易于维护。
#6楼
我认为你的选择是
- 使用为此目的而构建的地图实现,例如Google集合中的BiMap 。 请注意,Google集合BiMap要求值和键都是唯一的,但在双向性能上却表现出色
- 手动维护两个映射-一个映射为key-> value,另一个映射为value-> key
- 遍历
entrySet()
并找到与该值匹配的键。 这是最慢的方法,因为它需要遍历整个集合,而其他两种方法则不需要。
#7楼
如果您使用自己的代码构建地图,请尝试将键和值放到地图中:
public class KeyValue {public Object key;public Object value;public KeyValue(Object key, Object value) { ... }
}map.put(key, new KeyValue(key, value));
然后,当您拥有一个值时,您也将拥有钥匙。
#8楼
是的,除非您按照这些不同答案所建议的方式实施某些操作,否则您必须遍历哈希图。 我只需要获取keySet(),然后遍历该集合,然后保留(第一个)键即可获得匹配的值,而不必摆弄entrySet。 如果您需要与该值匹配的所有键,那么显然您必须做整个事情。
正如乔纳斯(Jonas)所建议的那样,这可能已经是containsValue方法的作用,因此您可能会完全跳过该测试,并且每次都进行迭代(或者,编译器已经消除了冗余,这是众所周知的)。
另外,相对于其他答案,如果您的反向映射看起来像
Map<Value, Set<Key>>
如果需要此功能,则可以处理非唯一的key-> value映射(将它们放在一边)。 这可以很好地结合到人们使用两个地图建议的任何解决方案中。
#9楼
public static class SmartHashMap <T1 extends Object, T2 extends Object> {public HashMap<T1, T2> keyValue;public HashMap<T2, T1> valueKey;public SmartHashMap(){this.keyValue = new HashMap<T1, T2>();this.valueKey = new HashMap<T2, T1>();}public void add(T1 key, T2 value){this.keyValue.put(key, value);this.valueKey.put(value, key);}public T2 getValue(T1 key){return this.keyValue.get(key);}public T1 getKey(T2 value){return this.valueKey.get(value);}}
#10楼
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;public class ValueKeysMap<K, V> extends HashMap <K,V>{HashMap<V, Set<K>> ValueKeysMap = new HashMap<V, Set<K>>();@Overridepublic boolean containsValue(Object value) {return ValueKeysMap.containsKey(value);}@Overridepublic V put(K key, V value) {if (containsValue(value)) {Set<K> keys = ValueKeysMap.get(value);keys.add(key);} else {Set<K> keys = new HashSet<K>();keys.add(key);ValueKeysMap.put(value, keys);}return super.put(key, value);}@Overridepublic V remove(Object key) {V value = super.remove(key);Set<K> keys = ValueKeysMap.get(value);keys.remove(key);if(keys.size() == 0) {ValueKeysMap.remove(value);}return value;}public Set<K> getKeys4ThisValue(V value){Set<K> keys = ValueKeysMap.get(value);return keys;}public boolean valueContainsThisKey(K key, V value){if (containsValue(value)) {Set<K> keys = ValueKeysMap.get(value);return keys.contains(key);}return false;}/** Take care of argument constructor and other api's like putAll*/
}
#11楼
您可以将键,值对及其反向插入到地图结构中
map.put("theKey", "theValue");
map.put("theValue", "theKey");
然后使用map.get(“ theValue”)将返回“ theKey”。
我制作了常量映射是一种快速而肮脏的方法,它仅适用于少数几个数据集:
- 仅包含1对1
- 值集与键集不相交(1-> 2,2-> 3断开键)
#12楼
在java8中
map.entrySet().stream().filter(entry -> entry.getValue().equals(value)).forEach(entry -> System.out.println(entry.getKey()));
#13楼
我认为这是最好的解决方案,原始地址: Java2s
import java.util.HashMap;import java.util.Map;public class Main {public static void main(String[] argv) {Map<String, String> map = new HashMap<String, String>();map.put("1","one");map.put("2","two");map.put("3","three");map.put("4","four");System.out.println(getKeyFromValue(map,"three"));}// hm is the map you are trying to get value from itpublic static Object getKeyFromValue(Map hm, Object value) {for (Object o : hm.keySet()) {if (hm.get(o).equals(value)) {return o;}}return null;}}
一种简单的用法:如果将所有数据都放入hasMap中,并且具有item =“ Automobile”,那么您将在hashMap中查找其键。 那是很好的解决方案。
getKeyFromValue(hashMap, item);
System.out.println("getKeyFromValue(hashMap, item): "+getKeyFromValue(hashMap, item));
#14楼
如果您的数据结构在键和值之间具有多对一映射,则应遍历条目并选择所有合适的键:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {Set<T> keys = new HashSet<T>();for (Entry<T, E> entry : map.entrySet()) {if (Objects.equals(value, entry.getValue())) {keys.add(entry.getKey());}}return keys;
}
如果是一对一关系,则可以返回第一个匹配的键:
public static <T, E> T getKeyByValue(Map<T, E> map, E value) {for (Entry<T, E> entry : map.entrySet()) {if (Objects.equals(value, entry.getValue())) {return entry.getKey();}}return null;
}
在Java 8中:
public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {return map.entrySet().stream().filter(entry -> Objects.equals(entry.getValue(), value)).map(Map.Entry::getKey).collect(Collectors.toSet());
}
同样,对于Guava用户, BiMap可能会有用。 例如:
BiMap<Token, Character> tokenToChar = ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
#15楼
恐怕您只需要迭代地图即可。 我能想到的最短的时间是:
Iterator<Map.Entry<String,String>> iter = map.entrySet().iterator();
while (iter.hasNext()) {Map.Entry<String,String> entry = iter.next();if (entry.getValue().equals(value_you_look_for)) {String key_you_look_for = entry.getKey();}
}
#16楼
/*** This method gets the Key for the given Value* @param paramName* @return*/
private String getKeyForValueFromMap(String paramName) {String keyForValue = null;if(paramName!=null)) {Set<Entry<String,String>> entrySet = myMap().entrySet();if(entrySet!=null && entrySet.size>0) {for(Entry<String,String> entry : entrySet) {if(entry!=null && paramName.equalsIgnoreCase(entry.getValue())) {keyForValue = entry.getKey();}}}}return keyForValue;
}
#17楼
您可以使用以下代码使用值来获取密钥。
ArrayList valuesList = new ArrayList();
Set keySet = initalMap.keySet();
ArrayList keyList = new ArrayList(keySet);for(int i = 0 ; i < keyList.size() ; i++ ) {valuesList.add(initalMap.get(keyList.get(i)));
}Collections.sort(valuesList);
Map finalMap = new TreeMap();
for(int i = 0 ; i < valuesList.size() ; i++ ) {String value = (String) valuesList.get(i);for( int j = 0 ; j < keyList.size() ; j++ ) {if(initalMap.get(keyList.get(j)).equals(value)) {finalMap.put(keyList.get(j),value);} }
}
System.out.println("fianl map ----------------------> " + finalMap);
#18楼
值得注意的是,由于这个问题,Apache Collections支持Generic BidiMaps 。 因此,在这一点上,一些投票最多的答案不再准确。
对于也支持重复值的序列化BidiMap(一对多方案),请考虑MapDB.org 。
#19楼
for(int key: hm.keySet()) {if(hm.get(key).equals(value)) {System.out.println(key); }
}
#20楼
使用Java 8:
ftw.forEach((key, value) -> {if (value.equals("foo")) {System.out.print(key);}
});
#21楼
对于面向API <19的Android开发,Vitalii Fedorenko一对一关系解决方案不起作用,因为未实现Objects.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;
}
#22楼
用自己的实现装饰地图
class MyMap<K,V> extends HashMap<K, V>{Map<V,K> reverseMap = new HashMap<V,K>();@Overridepublic V put(K key, V value) {// TODO Auto-generated method stubreverseMap.put(value, key);return super.put(key, value);}public K getKey(V value){return reverseMap.get(value);}
}
#23楼
我的2美分。 您可以获取数组中的键,然后在数组中循环。 如果映射很大,这将影响此代码块的性能,在这种情况下,您首先要获取数组中的键,这可能会花费一些时间,然后循环。 否则,对于较小的地图应该没问题。
String[] keys = yourMap.keySet().toArray(new String[0]);for(int i = 0 ; i < keys.length ; i++){//This is your key String key = keys[i];//This is your valueyourMap.get(key)
}
#24楼
如果要从值中获取密钥,最好使用bidimap(双向映射),则可以在O(1)时间内从值中获取密钥。
但是,这样做的缺点是您只能使用唯一的键集和值集。
Java中有一个名为Table的数据结构,它不过是类似map的map
表格<A,B,C> ==映射<A,映射<B,C>>
在这里,您可以通过查询
T.row(a);
获得map<B,C>
T.row(a);
,还可以通过查询T.column(b);
获得map<A,C>
T.column(b);
在特殊情况下,将C插入为常数。
因此,它类似于<a1,b1,1> <a2,b2,1>,...
因此,如果通过T.row(a1)查找--->返回->的映射,则获取此返回映射的键集。
如果需要查找键值,则T.column(b2)->返回->的映射,获取返回映射的键集。
与以前相比的优势:
- 可以使用多个值。
- 使用大型数据集时效率更高。
#25楼
您可以使用以下内容:
public class HashmapKeyExist {public static void main(String[] args) {HashMap<String, String> hmap = new HashMap<String, String>();hmap.put("1", "Bala");hmap.put("2", "Test");Boolean cantain = hmap.containsValue("Bala");if(hmap.containsKey("2") && hmap.containsValue("Test")){System.out.println("Yes");}if(cantain == true){System.out.println("Yes"); }Set setkeys = hmap.keySet();Iterator it = setkeys.iterator();while(it.hasNext()){String key = (String) it.next();if (hmap.get(key).equals("Bala")){System.out.println(key);}}}
}
#26楼
public static String getKey(Map<String, Integer> mapref, String value) {String key = "";for (Map.Entry<String, Integer> map : mapref.entrySet()) {if (map.getValue().toString().equals(value)) {key = map.getKey();}}return key;
}
#27楼
我认为keySet()可能很好地找到映射到该值的键,并且比entrySet()更好的编码风格。
例如:
假设您有一个HashMap 映射 ArrayList res ,该值是您想要查找所有键映射的值 ,然后将键存储到res 。
您可以在下面编写代码:
for (int key : map.keySet()) {if (map.get(key) == value) {res.add(key);}}
而不是使用下面的entrySet():
for (Map.Entry s : map.entrySet()) {if ((int)s.getValue() == value) {res.add((int)s.getKey());}}
希望能帮助到你 :)
#28楼
尽管这并不能直接回答问题,但却是相关的。
这样,您无需继续创建/迭代。 只需创建一次反向映射即可获得所需的内容。
/*** Both key and value types must define equals() and hashCode() for this to work.* This takes into account that all keys are unique but all values may not be.** @param map* @param <K>* @param <V>* @return*/
public static <K, V> Map<V, List<K>> reverseMap(Map<K,V> map) {if(map == null) return null;Map<V, List<K>> reverseMap = new ArrayMap<>();for(Map.Entry<K,V> entry : map.entrySet()) {appendValueToMapList(reverseMap, entry.getValue(), entry.getKey());}return reverseMap;
}/*** Takes into account that the list may already have values.* * @param map* @param key* @param value* @param <K>* @param <V>* @return*/
public static <K, V> Map<K, List<V>> appendValueToMapList(Map<K, List<V>> map, K key, V value) {if(map == null || key == null || value == null) return map;List<V> list = map.get(key);if(list == null) {List<V> newList = new ArrayList<>();newList.add(value);map.put(key, newList);}else {list.add(value);}return map;
}
#29楼
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());}}}
}
一些其他信息...可能对您有用
如果您的哈希图很大,则上述方法可能不是很好。 如果您的哈希表包含唯一键到唯一值的映射,则可以再维护一个哈希表,其中包含从值到键的映射。
那就是你必须维护两个哈希图
1. Key to value2. Value to key
在这种情况下,您可以使用第二个哈希图来获取密钥。
#30楼
使用薄包装器: 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;}
}
Java Hashmap:如何从价值中获取关键?相关推荐
- java数据存在ie中_[Java教程]解决在IE中获取数据的缓存问题,运行环境为node.js
[Java教程]解决在IE中获取数据的缓存问题,运行环境为node.js 0 2015-11-30 20:00:06 IE下默认会开启缓存策略,不管是页面还是通过ajax请求的数据都会议一个url,u ...
- java 当前时间格式_JAVA中获取当前系统时间及格式转换
一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...
- java资源文件路径_Java 中获取资源(文件)的路径问题总结
Java 中获取资源(文件)的路径问题总结 首先,Java 中获取资源大体上可分为两种方式,基于 文件系统的 和 基于classpath的. 1. 基于文件系统的相对简单. 比如 构造一个File f ...
- java 获得当前时间_JAVA中获取当前系统时间
一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...
- java date当前时间_JAVA中获取当前系统时间
一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...
- Java 系统时间转为date_JAVA中获取当前系统时间及格式转换
一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleDateFormat; public class NowStri ...
- java输出当前时间_JAVA中获取当前系统时间 - Matrix54 - 博客园
JAVA中获取当前系统时间 - Matrix54 - 博客园 一. 获取当前系统时间和日期并格式化输出: import java.util.Date; import java.text.SimpleD ...
- java hashmap遍历顺序_Java中HashMap遍历的两种方式
第一种: Map map = HashMap(); Iterator iter = map.entrySet().iterator(); (iter.hasNext()) { Map.Entry e ...
- java获取jtable的路径,Java如何在JTable组件中获取选定的单元格?
以下示例显示如何获取选定的行或选定的列,或如何选择JTable组件中的多个单元格.要侦听选择事件,我们可以JTable通过调用JTable.getSelectionModel().addListSel ...
最新文章
- python长度分割文本_python 按照固定长度分割字符串的方法小结
- 马斯克直聘AI人才:高中毕没毕业无所谓,但是编程能力得过硬
- LINUX下查看主机信息
- 定点c程序之五:定点数的字长效应
- 牛客 - 街机争霸(bfs)
- 解决安装phpstudy之后启动Apache失败的问题
- #史上最详解# IIS服务器查看log日志
- k3服务器端的虚拟,k3服务器 客户端配置
- MySQL5.7默认打开ONLY_FULL_GROUP_BY模式问题与解决方案
- Sql查找断号区间...
- ❤️什么是Java 面向对象《装、继承、多态、抽象》?建议收藏)❤️
- vrrp 的mac是怎么算出来的_宇宙总质量约10^55kg,与大家掰一掰是怎么算出来的
- 如何在WP7中使用自定义字体
- 老罗Android开发视频教程(Android入门介绍)九集集合
- 全网最新Linux全套教程
- 高校实验室安全隐患及安全建设-LIMS2
- 前端请求报错Provisional headers are shown接口请求失败
- 4 JWS 的签名方式
- Android Studio实现简单计算器
- scaner从外网到内网域渗透笔记