जावा में कुंजी द्वारा मानचित्र मानों को कैसे छाँटा जाए?


361

मेरे पास एक मैप है जिसमें चाबियाँ और मूल्य दोनों के लिए तार हैं।

डेटा निम्नलिखित है:

"question1", "1"
"question9", "1"
"question2", "4"
"question5", "2"

मैं इसकी कुंजियों के आधार पर मानचित्र को क्रमबद्ध करना चाहता हूं। तो, अंत में, मेरे पास होगा question1, question2, question3.... और इसी तरह।


आखिरकार, मैं इस मानचित्र से दो तार निकालने की कोशिश कर रहा हूं।

  • पहला स्ट्रिंग: प्रश्न (क्रम में 1 ..10)
  • दूसरा स्ट्रिंग: उत्तर (प्रश्न के समान क्रम में)

अभी मेरे पास निम्नलिखित हैं:

Iterator it = paramMap.entrySet().iterator();
while (it.hasNext()) {
    Map.Entry pairs = (Map.Entry) it.next();
    questionAnswers += pairs.getKey() + ",";
}

यह मुझे एक स्ट्रिंग में प्रश्न देता है लेकिन वे क्रम में नहीं हैं।

जवाबों:


612

संक्षिप्त जवाब

एक का उपयोग करें TreeMap। यह वही है जो इसके लिए है।

यदि यह नक्शा आपके पास है और आप प्रकार का निर्धारण नहीं कर सकते हैं, तो आप निम्न कार्य कर सकते हैं:

SortedSet<String> keys = new TreeSet<>(map.keySet());
for (String key : keys) { 
   String value = map.get(key);
   // do something
}

यह कुंजी के प्राकृतिक क्रम में नक्शे में पुनरावृति करेगा।


लंबा जवाब

तकनीकी रूप से, आप किसी भी चीज का उपयोग कर सकते हैं जो लागू करता है SortedMap, लेकिन दुर्लभ मामलों को छोड़कर TreeMap, केवल एक Mapकार्यान्वयन का उपयोग करते हुए, आमतौर पर इसकी मात्रा को छोड़कर HashMap

उन मामलों के लिए जहां आपकी कुंजी एक जटिल प्रकार है जो तुलनीय को लागू नहीं करता है या फिर आप प्राकृतिक क्रम का उपयोग नहीं करना चाहते हैं TreeMapऔर आपके TreeSetपास अतिरिक्त निर्माता हैं जो आपको एक में पास करते हैं Comparator:

// placed inline for the demonstration, but doesn't have to be a lambda expression
Comparator<Foo> comparator = (Foo o1, Foo o2) -> {
        ...
    }

SortedSet<Foo> keys = new TreeSet<>(comparator);
keys.addAll(map.keySet());

जब एक का उपयोग कर याद रखें TreeMapया TreeSetयह की तुलना में अलग प्रदर्शन विशेषताओं होगा कि HashMapया HashSet। मोटे तौर पर बोलने वाले संचालन जो एक तत्व को ढूंढते हैं या सम्मिलित करते हैं, वह ओ (1) से ओ (लॉग (एन)) तक जाएगा

में HashMap, 1000 आइटम से 10,000 तक ले जाना वास्तव में किसी तत्व को देखने के लिए आपके समय को प्रभावित नहीं करता है, लेकिन TreeMapदेखने के समय के लिए लगभग 3 गुना धीमा होगा (लॉग 2 मानकर )। हर तत्व लुकअप के लिए १००० से १,००,००० की गति लगभग ६ गुना धीमी होगी।


मैं ट्रेमेप का उपयोग करने और लंबाई के आधार पर स्ट्रिंग कीज़ को सॉर्ट करने का प्रयास कर रहा हूं। मुझे लगता है कि मुझे असंगत पुनर्प्राप्ति परिणाम मिल रहे हैं। स्पष्ट रूप से क्योंकि TreeMap 0 के बराबर परिणाम को "बराबर" मानता है? निश्चित नहीं है कि इस मामले में इसका उपयोग कैसे किया जाए।
मार्क

1
तुलना () 0 का परिणाम 'बराबर' है। यदि आप एक तुलनित्र लिख रहे हैं जो स्ट्रिंग की लंबाई के अनुसार है, तो आपको एक सकारात्मक या नकारात्मक मान वापस करने की आवश्यकता है जिसके आधार पर स्ट्रिंग लंबी है, और केवल 0 तब वापस आती है जब दोनों तार एक ही लंबाई के हों। यदि a और b स्ट्रिंग्स हैं तो आप ऐसा कर सकते हैं जैसे `रिटर्न a.length () - b.length () (या यदि आप उन्हें दूसरी दिशा में क्रमबद्ध करना चाहते हैं तो मूल्यों को उल्टा कर सकते हैं)।
झेरिको

नमस्कार दोस्तों, अगर वह मैप्स को चाबियों के हिसाब से ऑर्डर करना चाहता है, जो कि यहां 1,2,3,4 है, तो इंसर्शन ऑर्डर क्या है .... क्यों नहीं हम लिंक्डहाशसेट का इस्तेमाल कर रहे हैं? हम केवल एक-एक करके सवाल डालते हैं, और यह प्रविष्टि के आदेश द्वारा आदेशित हो रहा है। क्या कुछ इससे मुझे मदद मिल सकती है?
कारोली

@Karoly LinkedHashSet आपके द्वारा सम्मिलित किए गए क्रम में तत्वों को पुनः प्राप्त करने के लिए काम करेगा। ओपी चाहता है कि तत्वों को कुछ पूर्वनिर्धारित क्रम में पुनः प्राप्त किया जाए, जो कि सम्मिलन आदेश के बावजूद है।
डेविड बेरी

@ क्रिकेट_007 कोड विशेष रूप से प्रदर्शित कर रहा है कि कैसे वे उस नक्शे के लिए कुंजियों को पुनरावृत्त करें जो पहले से सॉर्ट नहीं किया गया है।
झेरिको

137

TreeMap मान लेना आपके लिए अच्छा नहीं है (और यह मानते हुए कि आप जेनरिक का उपयोग नहीं कर सकते हैं):

List sortedKeys=new ArrayList(yourMap.keySet());
Collections.sort(sortedKeys);
// Do what you need with sortedKeys.

3
धन्यवाद! मुझे ऐसा कुछ करने की ज़रूरत थी क्योंकि मेरी चाबियाँ एक जटिल प्रकार थीं।
रॉस हैम्ब्रिक जूल

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

55

TreeMapआप का उपयोग कर नक्शे को सॉर्ट कर सकते हैं।

Map<String, String> map = new HashMap<>();        
Map<String, String> treeMap = new TreeMap<>(map);
for (String str : treeMap.keySet()) {
    System.out.println(str);
}

1
नक्शा <स्ट्रिंग, सूची <स्ट्रिंग >> ट्रीपेज़ = नया ट्रीपैप <स्ट्रिंग, सूची <स्ट्रिंग >> (प्रिंटहैश मैप); for (स्ट्रिंग str: treeMap.keySet ()) {System.out.println (str + "" + treeMap.get (str)); }
विक्रमवी

37

ट्रीपाइप का उपयोग करें !


31
+1 - जेरीको, जॉन को हराने के लिए पर्याप्त नहीं, लेकिन फिर भी बहुत अच्छा। 8)
duffymo

मुझे नहीं पता जावा :-( यह 100% काम करता है। मेरे द्वारा किए गए किसी भी भयानक समाधान की तुलना में बहुत सरल
पेटेरकुला

36

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

Map<String, String> treeMap = new TreeMap<String, String>(yourMap);

एक पूर्ण कार्य उदाहरण:

import java.util.HashMap;
import java.util.Set;
import java.util.Map;
import java.util.TreeMap;
import java.util.Iterator;

class SortOnKey {

public static void main(String[] args) {
   HashMap<String,String> hm = new HashMap<String,String>();
   hm.put("3","three");
   hm.put("1","one");
   hm.put("4","four");
   hm.put("2","two");
   printMap(hm);
   Map<String, String> treeMap = new TreeMap<String, String>(hm);
   printMap(treeMap);
}//main

public static void printMap(Map<String,String> map) {
    Set s = map.entrySet();
    Iterator it = s.iterator();
    while ( it.hasNext() ) {
       Map.Entry entry = (Map.Entry) it.next();
       String key = (String) entry.getKey();
       String value = (String) entry.getValue();
       System.out.println(key + " => " + value);
    }//while
    System.out.println("========================");
}//printMap

}//class

36

बस TreeMap का उपयोग करें

new TreeMap<String, String>(unsortMap);

विदित हो कि ट्री मैप को उसकी 'कुंजियों' के प्राकृतिक क्रम के अनुसार क्रमबद्ध किया गया है।


19

बशर्ते आप उपयोग नहीं कर सकते हैं TreeMap, Java 8 में हम toMap () पद्धति का उपयोग कर सकते हैं Collectorsजिसमें निम्नलिखित पैरामीटर लगते हैं:

  • कीमैप : चाबियाँ बनाने के लिए मैपिंग फंक्शन
  • वैल्यूएम्पर : मान उत्पन्न करने के लिए मैपिंग फ़ंक्शन
  • मर्जफंक्शन : एक मर्ज फ़ंक्शन, जिसका उपयोग एक ही कुंजी से जुड़े मूल्यों के बीच टकराव को हल करने के लिए किया जाता है
  • mapSupplier : एक फ़ंक्शन जो एक नया, खाली मैप लौटाता है जिसमें परिणाम डाले जाएंगे।

जावा 8 उदाहरण

Map<String,String> sample = new HashMap<>();  // push some values to map  
Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                    .sorted(Map.Entry.<String,String>comparingByKey().reversed())
                    .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
Map<String, String> newMapSortedByValue = sample.entrySet().stream()
                        .sorted(Map.Entry.<String,String>comparingByValue().reversed())
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));

हम कस्टम तुलनित्र का उपयोग करने और कुंजियों के आधार पर छाँटने के लिए उदाहरण को संशोधित कर सकते हैं:

Map<String, String> newMapSortedByKey = sample.entrySet().stream()
                .sorted((e1,e2) -> e1.getKey().compareTo(e2.getKey()))
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1,e2) -> e1, LinkedHashMap::new));

केवल Api 24 और उच्चतर के साथ Android में काम करता है।
टीना

9

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

Map<String, Integer> sortedMap = unsortMap.entrySet().stream()
            .sorted(Map.Entry.comparingByKey())
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                    (oldValue, newValue) -> oldValue, LinkedHashMap::new));

5

यह कोड दोनों क्रमों में आरोही और अवरोही की-वैल्यू मैप को सॉर्ट कर सकता है।

<K, V extends Comparable<V>> Map<K, V> sortByValues
     (final Map<K, V> map, int ascending)
{
     Comparator<K> valueComparator =  new Comparator<K>() {         
        private int ascending;
        public int compare(K k1, K k2) {
            int compare = map.get(k2).compareTo(map.get(k1));
            if (compare == 0) return 1;
            else return ascending*compare;
        }
        public Comparator<K> setParam(int ascending)
        {
            this.ascending = ascending;
            return this;
        }
    }.setParam(ascending);

    Map<K, V> sortedByValues = new TreeMap<K, V>(valueComparator);
    sortedByValues.putAll(map);
    return sortedByValues;
}

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

Map<Integer,Double> recommWarrVals = new HashMap<Integer,Double>();
recommWarrVals = sortByValues(recommWarrVals, 1);  // Ascending order
recommWarrVals = sortByValues(recommWarrVals,-1);  // Descending order

5

जावा 8 में

Map<K, V>कुंजी के आधार पर छाँटने के लिए List<K>:

List<K> result = map.keySet().stream().sorted().collect(Collectors.toList());

Map<K, V>कुंजी के आधार पर छाँटने के लिए , प्रविष्टियाँ एक में डाल रही हैं List<Map.Entry<K, V>>:

List<Map.Entry<K, V>> result =
    map.entrySet()
       .stream()
       .sorted(Map.Entry.comparingByKey())
       .collect(Collectors.toList());

अंतिम लेकिन कम से कम नहीं: स्थानीय-संवेदनशील तरीके से तार को सॉर्ट करने के लिए - एक Collator (तुलनित्र) वर्ग का उपयोग करें:

Collator collator = Collator.getInstance(Locale.US);
collator.setStrength(Collator.PRIMARY); // case insensitive collator

List<Map.Entry<String, String>> result =
    map.entrySet()
       .stream()
       .sorted(Map.Entry.comparingByKey(collator))
       .collect(Collectors.toList());

1
List<String> list = new ArrayList<String>();
Map<String, String> map = new HashMap<String, String>();
for (String str : map.keySet()) {
 list.add(str);
}
Collections.sort(list);
for (String str : list) {
 System.out.println(str);
}

1

Java 8 में आप .stream () का उपयोग कर सकते हैं। सॉर्ट किया गया ():

myMap.keySet().stream().sorted().forEach(key -> {
        String value = myMap.get(key);

        System.out.println("key: " + key);
        System.out.println("value: " + value);
    }
);

0

हम Arrays.sort पद्धति का उपयोग करके कुंजी को सॉर्ट भी कर सकते हैं।

Map<String, String> map = new HashMap<String, String>();
Object[] objArr = new Object[map.size()];
for (int i = 0; i < map.size(); i++) {
objArr[i] = map.get(i);
}
Arrays.sort(objArr);
for (Object str : objArr) {
System.out.println(str);
}

यह मूल्य के आधार पर छँटाई है और कुंजी नहीं है।
राज

0

बस के मामले में आप एक का उपयोग नहीं करना चाहते हैं TreeMap

public static Map<Integer, Integer> sortByKey(Map<Integer, Integer> map) {
    List<Map.Entry<Integer, Integer>> list = new ArrayList<>(map.entrySet());
    list.sort(Comparator.comparingInt(Map.Entry::getKey));
    Map<Integer, Integer> sortedMap = new HashMap<>();
    list.forEach(sortedMap.put(e.getKey(), e.getValue()));
    return sortedMap;
}

इसके अलावा, इन-मामला आप के आधार पर अपने नक्शे को सॉर्ट करना चाहता था valuesसिर्फ परिवर्तन Map.Entry::getKeyकरने के लिएMap.Entry::getValue


यह मेरी समीक्षा लॉग में आया। किसी ने चर नाम (लेकिन विफल) के साथ कुछ त्रुटियों को ठीक करने की कोशिश की। इसलिए, मैंने उन्हें सही ढंग से निर्धारित किया है, हालांकि, यह उत्तर मूल रूप से गलत है। जिस क्रम में आप किसी HashMap में मान जोड़ते हैं वह अप्रासंगिक है। नक्शे में आदेश नहीं है। stackoverflow.com/questions/10710193/…
aepryus
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.