如果我的价值"foo",以及HashMap<String> ftw对于其ftw.containsValue("foo")返回true,我怎么能得到相应的钥匙?我是否必须遍历hashmap?最好的方法是什么?
Vit*_*nko 593
如果您的数据结构在键和值之间具有多对一映射,则应迭代条目并选择所有合适的键:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果是一对一关系,您可以返回第一个匹配的密钥:
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;
}
Run Code Online (Sandbox Code Playgroud)
在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());
}
Run Code Online (Sandbox Code Playgroud)
此外,对于Guava用户,BiMap可能很有用.例如:
BiMap<Token, Character> tokenToChar =
ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);
Run Code Online (Sandbox Code Playgroud)
Vin*_*lds 208
如果您选择使用Commons Collections库而不是标准Java Collections API,则可以轻松实现此目的.
Collections库中的BidiMap接口是一个双向映射,允许您将键映射到值(如法线贴图),还可以将值映射到键,从而允许您在两个方向上执行查找.getKey()方法支持获取值的键.
但有一点需要注意,比迪映射不能将多个值映射到键,因此除非您的数据集在键和值之间具有1:1的映射,否则您无法使用bidimaps.
更新
如果要依赖Java Collections API,则必须确保在将值插入映射时键和值之间的1:1关系.这说起来容易做起来难.
一旦可以确保,使用entrySet()方法获取Map中的条目集(映射).获得类型为Map.Entry的集合后,迭代条目,将存储的值与预期值进行比较,并获取相应的密钥.
更新#2
可以在Google Guava和重构的Commons-Collections库(后者不是Apache项目)中找到对带有泛型的bidi地图的支持.感谢Esko指出Apache Commons Collections中缺少的通用支持.使用带有泛型的集合可以使代码更易于维护.
Fat*_*n P 73
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());
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
一些额外的信息...可能对您有用
如果你的hashmap真的很大,上面的方法可能不太好.如果您的hashmap包含唯一值映射的唯一键,则可以再维护一个包含从Value到Key的映射的hashmap.
那就是你必须保持两个哈希图
1. Key to value
2. Value to key
Run Code Online (Sandbox Code Playgroud)
在这种情况下,您可以使用第二个hashmap来获取密钥.
Chi*_*itz 18
您可以将键,值对及其反转插入到地图结构中
map.put("theKey", "theValue");
map.put("theValue", "theKey");
Run Code Online (Sandbox Code Playgroud)
然后使用map.get("theValue")将返回"theKey".
这是一种快速而肮脏的方式,我制作了恒定的地图,这只适用于少数几个数据集:
小智 15
使用您自己的实现装饰地图
class MyMap<K,V> extends HashMap<K, V>{
Map<V,K> reverseMap = new HashMap<V,K>();
@Override
public V put(K key, V value) {
// TODO Auto-generated method stub
reverseMap.put(value, key);
return super.put(key, value);
}
public K getKey(V value){
return reverseMap.get(value);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您在自己的代码中构建地图,请尝试将关键字和值一起放在地图中:
public class KeyValue {
public Object key;
public Object value;
public KeyValue(Object key, Object value) { ... }
}
map.put(key, new KeyValue(key, value));
Run Code Online (Sandbox Code Playgroud)
然后当你有一个值时,你也有了钥匙.
小智 9
我认为这是最好的解决方案,原始地址: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 it
public static Object getKeyFromValue(Map hm, Object value) {
for (Object o : hm.keySet()) {
if (hm.get(o).equals(value)) {
return o;
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
一个简单的用法:如果您将所有数据放在hasMap中并且您有item ="Automobile",那么您在hashMap中查找其关键字.这是很好的解决方案.
getKeyFromValue(hashMap, item);
System.out.println("getKeyFromValue(hashMap, item): "+getKeyFromValue(hashMap, item));
Run Code Online (Sandbox Code Playgroud)
使用Java 8:
ftw.forEach((key, value) -> {
if (value.equals("foo")) {
System.out.print(key);
}
});
Run Code Online (Sandbox Code Playgroud)
小智 6
我担心你只需要迭代你的地图.最短的我可以想出:
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();
}
}
Run Code Online (Sandbox Code Playgroud)
小智 6
for(int key: hm.keySet()) {
if(hm.get(key).equals(value)) {
System.out.println(key);
}
}
Run Code Online (Sandbox Code Playgroud)
对于针对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;
}
Run Code Online (Sandbox Code Playgroud)