Java Hashmap: How to get key from value?

前端 未结 30 1761
忘掉有多难
忘掉有多难 2020-11-22 02:14

If I have the value \"foo\", and a HashMap ftw for which ftw.containsValue(\"foo\") returns true, how can I

相关标签:
30条回答
  • 2020-11-22 03:18

    There is no unambiguous answer, because multiple keys can map to the same value. If you are enforcing unique-ness with your own code, the best solution is to create a class that uses two Hashmaps to track the mappings in both directions.

    0 讨论(0)
  • 2020-11-22 03:18

    For Android development targeting API < 19, Vitalii Fedorenko one-to-one relationship solution doesn't work because Objects.equals isn't implemented. Here's a simple alternative:

    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;
    }
    
    0 讨论(0)
  • 2020-11-22 03:18
    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);
        }
    
    }
    
    0 讨论(0)
  • 2020-11-22 03:18
    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>>();
    
        @Override
        public boolean containsValue(Object value) {
            return ValueKeysMap.containsKey(value);
        }
    
        @Override
        public 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);
        }
    
        @Override
        public 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
         */
    }
    
    0 讨论(0)
  • 2020-11-22 03:18
    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);
        }
    }
    
    0 讨论(0)
  • 2020-11-22 03:19

    If your data structure has many-to-one mapping between keys and values you should iterate over entries and pick all suitable keys:

    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;
    }
    

    In case of one-to-one relationship, you can return the first matched key:

    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;
    }
    

    In 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());
    }
    

    Also, for Guava users, BiMap may be useful. For example:

    BiMap<Token, Character> tokenToChar = 
        ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
    Token token = tokenToChar.inverse().get('(');
    Character c = tokenToChar.get(token);
    
    0 讨论(0)
提交回复
热议问题