Java में Map को मानों के अनुसार क्रमबद्ध करना: पुरानी (और नई) गलतियों से कैसे बचें
\n\n«मुझे HashMap को मानों के अनुसार क्रमबद्ध करना है!» — Stack Overflow पर यह प्रश्न हज़ारों बार देखा जाता है और दर्जनों उत्तर मिलते हैं। लगता है इससे आसान क्या हो सकता है? Map लिया, values() के अनुसार क्रमबद्ध किया… और सिरदर्द मिला। क्योंकि Java में Map को मानों के अनुसार क्रमबद्ध करना एक ऐसा कार्य है जहाँ शुरुआती (और अनुभवी डेवलपर भी) बार-बार वही गलतियाँ करते हैं।
इस लेख में हम HashMap को मानों के अनुसार क्रमबद्ध करने की 5 सबसे सामान्य गलतियों पर चर्चा करेंगे, सही समाधान दिखाएंगे और तैयार कोड टेम्पलेट देंगे। चलिए शुरू करते हैं!
\n\nगलती #1: HashMap को सीधे क्रमबद्ध करने का भोला प्रयास
\n\nसबसे आम गलती यह सोचना है कि HashMap को «उसी स्थान पर» क्रमबद्ध किया जा सकता है। HashMap तत्वों के क्रम की गारंटी नहीं देता — यह इसका मूलभूत गुण है। आप HashMap पर sort() कॉल नहीं कर सकते, क्योंकि इसके पास ऐसा कोई तरीका नहीं है।
यहाँ बताया गया है कि कैसे नहीं करना चाहिए:
\n\n// ❌ गलती: HashMap को सीधे क्रमबद्ध नहीं किया जा सकता\nMap<String, Integer> scores = new HashMap<>();\nscores.put("Alice", 95);\nscores.put("Bob", 80);\nscores.put("Charlie", 90);\n\n// ऐसा कोई तरीका नहीं है!\n// scores.sort(...); // संकलन त्रुटि\n\nयह काम क्यों नहीं करता? HashMap कुंजी-मान जोड़े को संग्रहीत करने के लिए हैशिंग का उपयोग करता है। क्रम कुंजियों के हैश-कोड द्वारा निर्धारित होता है और नए तत्व जोड़ने पर बदल सकता है। Map को मानों के अनुसार क्रमबद्ध करना केवल एक नई डेटा संरचना — जैसे LinkedHashMap — बनाकर ही संभव है।
सही समाधान: एक नया LinkedHashMap बनाएँ
\n\n// ✅ सही: Entry को क्रमबद्ध करें और LinkedHashMap में सहेजें\nMap<String, Integer> sortedMap = scores.entrySet()\n .stream()\n .sorted(Map.Entry.comparingByValue())\n .collect(Collectors.toMap(\n Map.Entry::getKey,\n Map.Entry::getValue,\n (e1, e2) -> e1, // विरोधों को हल करें (यदि कुंजियाँ दोहराई जाती हैं)\n LinkedHashMap::new // सम्मिलन क्रम बनाए रखें\n ));\n\nSystem.out.println(sortedMap);\n// {Bob=80, Charlie=90, Alice=95} — आरोही क्रम में क्रमबद्ध!\n\nगलती #2: संग्रह करते समय LinkedHashMap के बारे में भूल जाना
\n\nअनुभवी Java डेवलपर भी कभी-कभी ऐसा कोड लिखते हैं:
\n\n// ⚠️ लगभग सही, लेकिन एक बारीकी है\nMap<String, Integer> result = scores.entrySet()\n .stream()\n .sorted(Map.Entry.comparingByValue())\n .collect(Collectors.toMap(\n Map.Entry::getKey,\n Map.Entry::getValue\n )); // डिफ़ॉल्ट रूप से Collectors.toMap() HashMap बनाता है!\n\nक्या है पेंच? Collectors.toMap() बिना आपूर्तिकर्ता (supplier) निर्दिष्ट किए HashMap बनाता है। और HashMap क्रम की गारंटी नहीं देता! आपकी क्रमबद्धता निष्पादित हो जाएगी, लेकिन परिणाम अक्रमबद्ध दिख सकता है। यह Map को क्रमबद्ध करते समय Java की सबसे कपटी त्रुटियों में से एक है।
कैसे ठीक करें
\n\nहमेशा चौथे तर्क के रूप में स्पष्ट रूप से LinkedHashMap::new निर्दिष्ट करें:
// ✅ निश्चित रूप से सही\nMap<String, Integer> result = scores.entrySet()\n .stream()\n .sorted(Map.Entry.comparingByValue())\n .collect(Collectors.toMap(\n Map.Entry::getKey,\n Map.Entry::getValue,\n (oldVal, newVal) -> oldVal,\n LinkedHashMap::new // महत्वपूर्ण बिंदु!\n ));\n\nगलती #3: मानों के अनुसार क्रमबद्ध करना जब वे Comparable न हों
\n\nमान लीजिए, आपके पास Map<String, CustomObject> है। आप लिखते हैं:
// ❌ गलती: CustomObject Comparable को लागू नहीं करता\nMap<String, CustomObject> map = new HashMap<>();\n// ...\nmap.entrySet().stream()\n .sorted(Map.Entry.comparingByValue()) // संकलन त्रुटि!\n