java - जावा हैशमैप: मूल्य से कुंजी कैसे प्राप्त करें?




hashmap (20)

अगर मेरे पास "foo" मान है, और ftw.containsValue("foo") HashMap<String> ftw जिसके लिए ftw.containsValue("foo") true लौटाता true , तो मैं संबंधित कुंजी कैसे प्राप्त कर सकता हूं? क्या मुझे हैशपैप के माध्यम से लूप करना है? उसे करने का सबसे अच्छा तरीका कौन सा है?


  1. यदि आप मूल्य से कुंजी प्राप्त करना चाहते हैं, तो बोलीमाप (द्वि-दिशात्मक मानचित्र) का उपयोग करने के लिए सबसे अच्छा, आप ओ (1) समय में मूल्य से कुंजी प्राप्त कर सकते हैं।

    लेकिन, इसके साथ दोष यह है कि आप केवल अद्वितीय कीसेट और वैसेट का उपयोग कर सकते हैं।

  2. टेबल में जावा नामक एक डेटा संरचना है, जो नक्शे के मानचित्र के अलावा कुछ भी नहीं है

    तालिका <ए, बी, सी> == मानचित्र <ए, मानचित्र <बी, सी>>

    यहां आप T.row(a); से पूछताछ करके map<B,C> प्राप्त कर सकते हैं T.row(a); , और आप T.column(b); map<A,C> भी प्राप्त कर सकते हैं T.column(b);

अपने विशेष मामले में, कुछ स्थिर के रूप में सी डालें।

तो, यह <ए 1, बी 1, 1> <ए 2, बी 2, 1>, जैसे ...

इसलिए, यदि आप T.row (a1) ---> के मानचित्र को प्राप्त करते हैं -> इस लौटाए गए मानचित्र को कीसेट प्राप्त करें।

यदि आपको कुंजी मान प्राप्त करने की आवश्यकता है, तो T.column (b2) -> का नक्शा वापस लौटाता है -> लौटाए गए मानचित्र की कीसेट प्राप्त करें।

पिछले मामले में लाभ:

  1. एकाधिक मानों का उपयोग कर सकते हैं।
  2. बड़े डेटा सेट का उपयोग करते समय अधिक कुशल।

अपने स्वयं के कार्यान्वयन के साथ मानचित्र सजाने के लिए

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

आप निम्नलिखित कोड का उपयोग कर मूल्यों का उपयोग कर कुंजी प्राप्त कर सकते हैं ..

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

आप नीचे का उपयोग कर सकते हैं:

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

एंड्रॉइड डेवलपमेंट लक्ष्यीकरण एपीआई <1 9 के लिए, 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;
}

एक पतली रैपर का प्रयोग करें: 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;
   }
}

कोई स्पष्ट जवाब नहीं है, क्योंकि एकाधिक कुंजी एक ही मूल्य पर मैप कर सकती हैं। यदि आप अपने कोड के साथ अद्वितीय-नस्ल लागू कर रहे हैं, तो सबसे अच्छा समाधान एक वर्ग बनाना है जो दोनों दिशाओं में मैपिंग को ट्रैक करने के लिए दो हैशमैप्स का उपयोग करता है।


जावा 8 का प्रयोग करना:

ftw.forEach((key, value) -> {
    if (value=="foo") {
        System.out.print(key);
    }
});

मुझे डर है कि आपको बस अपना नक्शा फिर से शुरू करना होगा। सबसे छोटा मैं इसके साथ आ सकता था:

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

मुझे लगता है कि keySet () मान पर मैपिंग कुंजी खोजने के लिए अच्छा हो सकता है, और प्रविष्टिसेट () से बेहतर कोडिंग शैली है।

उदाहरण के लिए:

मान लीजिए कि आपके पास हैश मैप नक्शा है , ArrayList res , एक मान जिसे आप सभी कुंजी मैपिंग ढूंढना चाहते हैं, फिर res को res को स्टोर करें।

आप नीचे कोड लिख सकते हैं:

    for (int key : map.keySet()) {
        if (map.get(key) == value) {
            res.add(key);
        }
    }

नीचे प्रविष्टिसेट () का उपयोग करने के बजाय:

    for (Map.Entry s : map.entrySet()) {
        if ((int)s.getValue() == value) {
            res.add((int)s.getKey());
        }
    }

आशा करता हूँ की ये काम करेगा :)


मुझे लगता है कि यह सबसे अच्छा समाधान है, मूल पता: Java2s 2 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;
          }
        }

एक आसान उपयोग: यदि आप हैसैप में सभी डेटा डालते हैं और आपके पास आइटम = "ऑटोमोबाइल" है, तो आप हैश मैप में इसकी कुंजी देख रहे हैं। यह अच्छा समाधान है।

getKeyFromValue(hashMap, item);
System.out.println("getKeyFromValue(hashMap, item): "+getKeyFromValue(hashMap, item));

मेरे 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 value
    yourMap.get(key)            
}

यदि आप मानक जावा कलेक्शन एपीआई के बजाय कॉमन्स कलेक्शन लाइब्रेरी का उपयोग करना चुनते हैं, तो आप इसे आसानी से प्राप्त कर सकते हैं।

कलेक्शन लाइब्रेरी में BidiMap इंटरफ़ेस एक द्वि-दिशात्मक मानचित्र है, जो आपको किसी मान (जैसे सामान्य मानचित्र) की कुंजी को मैप करने की अनुमति देता है, और एक कुंजी को एक मूल्य मैप करने की अनुमति देता है, जिससे आप दोनों दिशाओं में लुकअप निष्पादित कर सकते हैं। किसी मान के लिए कुंजी प्राप्त करना getKey () विधि द्वारा समर्थित है।

हालांकि एक चेतावनी है, बिडी मानचित्रों में कुंजी के लिए मैप किए गए एकाधिक मान नहीं हो सकते हैं, और इसलिए जब तक आपके डेटा सेट में कुंजी और मानों के बीच 1: 1 मैपिंग नहीं है, तो आप बोली-प्रक्रिया का उपयोग नहीं कर सकते हैं।

अद्यतन करें

यदि आप जावा कलेक्शन एपीआई पर भरोसा करना चाहते हैं, तो आपको मानचित्र में मूल्य डालने के समय कुंजी और मूल्यों के बीच 1: 1 संबंध सुनिश्चित करना होगा। ऐसा करना मुश्किल लेकिन कहना आसान है।

एक बार जब आप यह सुनिश्चित कर सकें, तो मानचित्र में प्रविष्टियों (मैपिंग) के सेट को प्राप्त करने के लिए एंट्रीसेट () विधि का उपयोग करें। एक बार जब आप सेट प्राप्त कर लेते हैं जिसका प्रकार Map.Entry , प्रविष्टियों के माध्यम से पुनरावृत्त करें, संग्रहीत मूल्य की अपेक्षा की तुलना में तुलना करें, और संबंधित कुंजी प्राप्त करें।

अद्यतन # 2

जेनेरिक के साथ बिडी मानचित्रों के लिए समर्थन Google Guava और रिफैक्टर Commons-Collections लाइब्रेरी में पाया जा सकता है (बाद वाला अपाचे प्रोजेक्ट नहीं है)। अपाचे कॉमन्स कलेक्शन में लापता सामान्य समर्थन को इंगित करने के लिए एस्को के लिए धन्यवाद। जेनेरिक के साथ संग्रह का उपयोग अधिक रखरखाव कोड बनाता है।


यदि आपकी डेटा संरचना में कुंजी और मानों के बीच कई-से-एक मानचित्रण है तो आपको प्रविष्टियों पर पुनरावृत्ति करना चाहिए और सभी उपयुक्त कुंजी चुनना चाहिए:

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

जावा 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());
}

इसके अलावा, गुवा उपयोगकर्ताओं के लिए, BiMap उपयोगी हो सकता है। उदाहरण के लिए:

BiMap<Token, Character> tokenToChar = 
    ImmutableBiMap.of(Token.LEFT_BRACKET, '[', Token.LEFT_PARENTHESIS, '(');
Token token = tokenToChar.inverse().get('(');
Character c = tokenToChar.get(token);

हां, आपको हैशपैप के माध्यम से लूप करना है, जब तक कि आप इन विभिन्न उत्तरों के सुझावों के आधार पर कुछ लागू नहीं करते हैं। एंट्रीसेट के साथ झुकाव करने के बजाय, मुझे केवल कुंजी सेट (), उस सेट पर फिर से मिल जाएगा, और (पहली) कुंजी रखें जो आपको अपना मिलान मूल्य प्राप्त करे। अगर आपको उस मूल्य से मेल खाने वाली सभी चाबियों की ज़रूरत है, तो जाहिर है कि आपको पूरी चीज करना है।

जैसा कि जोनास सुझाव देता है, यह हो सकता है कि इसमें वैल्यू विधि क्या हो रही है, इसलिए आप केवल उस परीक्षण को सभी को छोड़ सकते हैं, और हर बार पुनरावृत्ति कर सकते हैं (या शायद संकलक पहले से ही अनावश्यकता को खत्म कर देगा, जो जानता है)।

इसके अलावा, अन्य उत्तरों के सापेक्ष, यदि आपका रिवर्स मैप दिखता है

Map<Value, Set<Key>>

यदि आप उस क्षमता की आवश्यकता है (उन्हें अलग कर दें) तो आप गैर-अद्वितीय कुंजी-> मूल्य मैपिंग से निपट सकते हैं। इससे दो मानचित्रों का उपयोग करने वाले सुझावों में से किसी भी समाधान में जुर्माना शामिल होगा।


हालांकि यह सीधे सवाल का जवाब नहीं देता है, यह संबंधित है।

इस तरह आपको बनाने / पुनरावृत्ति रखने की आवश्यकता नहीं है। बस एक बार एक रिवर्स मानचित्र बनाएं और आपको जो चाहिए उसे प्राप्त करें।

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

for(int key: hm.keySet()) {
    if(hm.get(key).equals(value)) {
        System.out.println(key); 
    }
}

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

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 value

2. Value to key 

उस स्थिति में आप कुंजी प्राप्त करने के लिए दूसरे हैशपैप का उपयोग कर सकते हैं।


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




hashmap