2014-10-31 25 views
6

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

public class WordFrequency { 
    public static String sentence = "one three two two three three four four four"; 
    public static Map<String, Integer> map; 

    public static void main(String[] args) { 
     map = new HashMap<>(); 
     String[] words = sentence.split("\\s"); 

     for (String word : words) { 
      Integer count = map.get(word); 
      if (count == null) { 
       count = 1; 
      } else { 
       ++count; 
      } 
      map.put(word, count); 
     } 

     Comparator<String> myComparator = new Comparator<String>() { 

      @Override 
      public int compare(String s1, String s2) { 
       if (map.get(s1) < map.get(s2)) { 
        return -1; 
       } else if (map.get(s1) > map.get(s2)) { 
        return 1; 
       } else { 
        return 0; 
       } 
      } 

     }; 
     SortedMap<String, Integer> sortedMap = new TreeMap<String, Integer>(myComparator); 
     System.out.println("Before sorting: " + map); 
     sortedMap.putAll(map); 
     System.out.println("After Sorting based on value:" + sortedMap); 

    } 
} 

आउटपुट:

Before sorting: {two=2, one=1, three=3, four=3} 
After sorting based on value:{one=1, two=2, three=3} 

अपेक्षित आउटपुट:

{one=1, two=2, four=3,three=3} 
+0

क्या इसके बारे में अजीब है? –

+0

संभवतः ट्री-मैप does not को अनुमति देने के डुप्लिकेट –

+0

@SotiriosDelimanolis चार = 3 –

उत्तर

5

आपका compare विधि, मानचित्र इंटरफेस के अनुबंध का पालन करने के बाद से यह कुंजी के बजाय मूल्यों तुलना विफल रहता है। आपके कार्यान्वयन के लिए एक ही मान के साथ दो कुंजी का कारण एक ही कुंजी माना जाता है। इसलिए आपके sortedMap में "चार" कुंजी नहीं है, जिसमें "तीन" कुंजी के समान मूल्य है।

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

TreeMap reference

आप कुंजी तुलना द्वारा इस समस्या को ठीक कर सकते हैं जब मान बराबर हैं: four<three के बाद से

After sorting based on value:{one=1, two=2, four=3, three=3} 

:

Comparator<String> myComparator = new Comparator<String>() { 

     @Override 
     public int compare(String s1, String s2) { 
      if (map.get(s1) < map.get(s2)) { 
       return -1; 
      } else if (map.get(s1) > map.get(s2)) { 
       return 1; 
      } else { 
       return s1.compareTo(s2); 
      } 
     } 

    }; 

यह आप में से एक आउटपुट देना चाहिए स्ट्रिंग्स के प्राकृतिक क्रम पर आधारित है।

4

अपने compare() की वजह से केवल Map में मूल्यों पर विचार है। फिर three=3, four=3 समान मूल्य 3 है। फिर वे TreeMap में जोड़े जाने पर डुप्लीकेट के रूप में विचार करते हैं।

1

क्योंकि आपके कार्यान्वयन ट्री-मैप कि नक्शा [तीन] कह रहा है और नक्शा [चार] है कि अनिवार्य रूप से एक ही तत्व है, क्योंकि वे अपने तुलनित्र के अनुसार एक दूसरे के लिए "बराबर" कर रहे हैं।

बदलें "वापसी 0" तुलनाकारी में "वापस s1.compareTo (s2)" के लिए, और तुम होगा

Before sorting: {two=2, one=1, three=3, four=3} 
After Sorting based on value:{one=1, two=2, four=3, three=3} 

(मेरा मानना ​​है कि आप पता लगा सकते हैं क्यों "चार" से पहले "तीन" आता है इस मामले) में

+0

धन्यवाद @ मिंडेक्स मैंने इसे समझ लिया। –

संबंधित मुद्दे