जावा ऑर्डर किया गया नक्शा


322

जावा में, क्या कोई ऐसी वस्तु है जो कुंजी / मान युग्मों को संग्रहीत करने और उन तक पहुंचने के लिए एक मानचित्र की तरह काम करती है, लेकिन कुंजी की एक क्रमबद्ध सूची और मूल्यों की एक क्रमबद्ध सूची वापस कर सकती है, जैसे कि कुंजी और मूल्य सूची एक ही क्रम में हैं?

इसलिए स्पष्टीकरण-कोड के रूप में, मैं एक ऐसी चीज की तलाश कर रहा हूं जो मेरे काल्पनिक ऑर्डरडैप के समान व्यवहार करती है:

OrderedMap<Integer, String> om = new OrderedMap<>();
om.put(0, "Zero");
om.put(7, "Seven");

String o = om.get(7); // o is "Seven"
List<Integer> keys = om.getKeys();
List<String> values = om.getValues();

for(int i = 0; i < keys.size(); i++)
{
    Integer key = keys.get(i);
    String value = values.get(i);
    Assert(om.get(key) == value);
}

4
यदि आप सभी को एक ही समय में दोनों के माध्यम से पुनरावृत्त करना चाहते हैं, तो Map.entrySet () आपको किसी भी मानचित्र पर ऐसा करने देगा। LinkedHashMap में एक अच्छी तरह से परिभाषित आदेश है, लेकिन किसी भी मानचित्र के लिए प्रवेश सेट कुंजी / मूल्य जोड़े को दर्शाता है।
पीट किर्कम

5
यह कोड एक अच्छा उदाहरण नहीं है क्योंकि कोई भी मानचित्र कार्यान्वयन आपके नमूना कोड के रूप में व्यवहार करेगा। क्रमबद्ध, आदेशित या नहीं।
पीटर लॉरी

2
Sun JDK कार्यान्वयन में, getKeys और getValues ​​() सेट द्वारा लौटाए गए सेट मैप्स में entrySet () द्वारा समर्थित हैं, इसलिए इसमें वही पुनरावृत्ति क्रम होगा, जो आपका नमूना परीक्षण है।
पीट किर्कम

4
वैसे यह दिलचस्प है, मैंने कभी इस पर ध्यान नहीं दिया। फिर भी, मुझे पागल कहें, लेकिन मैं कार्यान्वयन के बारे में धारणाएं नहीं बनाना पसंद करता हूं जो इंटरफ़ेस द्वारा स्पष्ट रूप से सत्यापित नहीं हैं। मैं अतीत में ऐसा करते हुए कई बार जल चुका हूं।
व्हाट्सएप

2
इसका नाम Java Sorted Map होना चाहिए, क्योंकि ऑर्डर किया गया नक्शा कुछ अलग है - देखें LinkedHashMap
ओंद्र kaइस्का

जवाबों:


397

SortedMap इंटरफेस (कार्यान्वयन के साथ ट्री-मैप ) अपने दोस्त होना चाहिए।

इंटरफ़ेस में विधियाँ हैं:

  • keySet() जो आरोही क्रम में कुंजियों का एक सेट लौटाता है
  • values() जो संबंधित कुंजी के आरोही क्रम में सभी मानों का संग्रह लौटाता है

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


2
उदाहरण: SortedMap <स्ट्रिंग, ऑब्जेक्ट> मैप = नया ट्रीपैप <> ();
बेन

7
TreeMap का उपयोग करने के लिए यह आवश्यक है कि कुंजी वर्ग को तुलनात्मक इंटरफ़ेस लागू करना पड़े। यदि नहीं, तो किसी प्रकार की RuntimeException को फेंक दिया जाएगा। ट्री मैप यह भी मैप सॉर्ट किया गया है, लेकिन मुझे लगता है कि लेखक केवल ऑर्डर किए गए (सॉर्ट किए गए) मैप का उपयोग करना चाहता है। LinkedHashMap केवल ऑर्डर किए गए नक्शे को प्राप्त करना अच्छा विकल्प है (जैसा कि आपने कहा, "सम्मिलन आदेश द्वारा निर्धारित")।
। गोल

1
यह उत्तर दिखा सकता है कि किस तरह से इसे प्रदर्शित किया जा सकता है। KeySet ()

4
से जावा 8 डॉकLinkedHashMapकिसके क्रम का पुनरावृत्ति वह क्रम है जिसमें इसकी प्रविष्टियां अंतिम बार एक्सेस की गई थीं
TRINE

1
@TRiNE मैं आपकी टिप्पणी का पालन नहीं करता, लेकिन मैं कुछ संदर्भ याद कर सकते हैं। डिफ़ॉल्ट रूप से LinkedHashMapपुनरावृत्ति क्रम सम्मिलन-क्रम है, लेकिन आप एक्सेस-ऑर्डर को निर्दिष्ट करने के लिए एक अलग कंस्ट्रक्टर का उपयोग कर सकते हैं। docs.oracle.com/javase/8/docs/api/java/util/...
लूटने

212

क्या कोई ऐसी वस्तु है जो कुंजी / मान युग्मों को संग्रहीत करने और उन तक पहुँचने के लिए एक मानचित्र की तरह काम करती है, लेकिन कुंजी की एक क्रमबद्ध सूची और मूल्यों की एक क्रमबद्ध सूची वापस कर सकती है, जैसे कि कुंजी और मूल्य सूची एक ही क्रम में हैं?

आप java.util.LinkedHashMap की तलाश कर रहे हैं । आपको Map.Entry <K, V> जोड़े की सूची मिलेगी , जो हमेशा एक ही क्रम में पुनरावृत्त होते हैं। यह आदेश उसी तरह का है जिस क्रम से आप आइटम डालते हैं। वैकल्पिक रूप से, java.util.SreadMap का उपयोग करें , जहां कुंजियों को या तो प्राकृतिक ऑर्डर करना होगा या इसे निर्दिष्ट करना होगा Comparator


14
और इसे पढ़ने वाले को डबल चेक करने के लिए, क्योंकि परीक्षण द्वारा सत्यापित करना कठिन है, keySet()विधि प्रभावी रूप से एक लिंक्डहैशसेट लौटाती है जो आपकी put()कॉल के आदेश को दर्शाती है । ध्यान दें कि put()एक ही कुंजी के लिए बार-बार कॉल करने से ऑर्डर तब तक नहीं बदलेगा जब तक आप remove()पहले से चाबी नहीं देते।
ग्लेन लॉरेंस

से जावा 8 डॉकLinkedHashMapकिसके आदेश का पुनरावृत्ति क्रम है जिसमें इसकी प्रविष्टियां अंतिम बार एक्सेस की गई थीं
TRINE

24

LinkedHashMap कुंजियों के क्रम को बनाए रखता है।

java.util.LinkedHashMap सिर्फ एक सामान्य हैशपॉइंट की तरह ही काम करता है।


1
यह प्रश्न का उत्तर प्रदान नहीं करता है। किसी लेखक से स्पष्टीकरण मांगने या उसका स्पष्टीकरण देने के लिए, उनके पोस्ट के नीचे एक टिप्पणी छोड़ दें - आप हमेशा अपने स्वयं के पोस्ट पर टिप्पणी कर सकते हैं, और एक बार जब आप पर्याप्त प्रतिष्ठा पा लेंगे तो आप किसी भी पोस्ट पर टिप्पणी कर पाएंगे ।
29नया

2
@ ianaya89 मुझे लगता है कि यह एक वास्तविक जवाब है, लेकिन यह जॉन फेमिनाला के जवाब के समान है !
T30

1
यदि आप एक ऑर्डर किया गया नक्शा प्राप्त करना चाहते हैं, जहाँ प्रविष्टियाँ उस क्रम में संग्रहीत की जाती हैं, जैसा कि आप उन्हें मैप में डालते हैं, तो LinkedHashMap की तुलना में सही उत्तर है। यदि आप अपने नक्शे में प्रविष्टियों को स्वतंत्र रूप से क्रमबद्ध करना चाहते हैं, तो आप उन्हें क्रमबद्ध रूप से जिस क्रम में रखते हैं, वह सही उत्तर है।
राल्फ

@TRiNE जावा 8 डॉक जो आपने कहा है कि दो ऑर्डरिंग मोड संभव हैं: प्रविष्टि-ऑर्डर और एक्सेस-ऑर्डर। आप बाद के बारे में सोचते हैं जो एक विशेष कंस्ट्रक्टर पब्लिक लिंक्डहैशपप (इंट इनिशियल कैपासिटी, फ्लोट लोडफैक्टर, बूलियन एक्सेसऑर्डर) के उपयोग से लगाया जाता है। डिफॉल्ट कंस्ट्रक्टर एक इंसर्शन-आर्डर किया हुआ लिंक्डहैशमैप उदाहरण बनाता है।
अर्तुर Artयसिक

1
@ ArturŁysik हाँ यह है। यह मेरे द्वारा कुछ दिनों पहले की गई गलती थी। मैं इसे सही कर दूंगा। मैं टिप्पणी हटा रहा हूं। जैसा कि मैं अब इसे संपादित नहीं कर सकता हूं
TRINE

7

मुझे लगता है कि फ्रेमवर्क से आपको जो निकटतम संग्रह मिलेगा, वह है SortedMap


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

@CorayThan, उस मामले में आप सबसे अच्छे उत्तरों को बढ़ाते हैं, दूसरों को नीचा नहीं दिखाते हैं जो सही हो सकते हैं लेकिन सबसे अच्छे नहीं ...
bruno conde

1
वही मैंने किया। बस मैं कह रहा हूं कि कोई समझ सकता है कि कोई इसे क्यों वोट देगा।
18

5

आप NavigableMap इंटरफ़ेस का लाभ उठा सकते हैं जो कि आरोही या अवरोही प्रमुख क्रम में पहुँचा और ट्रेस किया जा सकता है। इस इंटरफ़ेस को SortedMap इंटरफ़ेस को सुपरसेड करने का इरादा है । नेविगेट करने योग्य नक्शा आमतौर पर इसकी कुंजियों के प्राकृतिक क्रम के अनुसार, या मानचित्र निर्माण के समय प्रदान किए गए एक तुलनित्र द्वारा क्रमबद्ध किया जाता है।

इसके तीन सबसे उपयोगी कार्यान्वयन हैं: ट्रीपाउप , इम्यूटेबलश्रुटपॉइंट , और समवर्तीसिक्लिपिस्टास्ट

ट्रीपैप उदाहरण:

TreeMap<String, Integer> users = new TreeMap<String, Integer>();
users.put("Bob", 1);
users.put("Alice", 2);
users.put("John", 3);

for (String key: users.keySet()) {
  System.out.println(key + " (ID = "+ users.get(key) + ")");
}

आउटपुट:

Alice (ID = 2)
Bob (ID = 1)
John (ID = 3)



2

tl; डॉ

Map< Integer , String >कुंजी द्वारा क्रमबद्ध क्रम में रखने के लिए SortedMap/ NavigableMapइंटरफेस लागू करने वाले दो वर्गों में से किसी एक का उपयोग करें:

  • TreeMap
  • ConcurrentSkipListMap

यदि एक ही धागे के भीतर मानचित्र में हेरफेर किया जाता है, तो पहले का उपयोग करें TreeMap। यदि धागे में हेरफेर, दूसरे का उपयोग करें ConcurrentSkipListMap

विवरण के लिए, नीचे दी गई तालिका और निम्न चर्चा देखें।

विवरण

यहां एक ग्राफिक टेबल है जिसे मैंने Mapजावा 11 के साथ बंडल किए गए दस कार्यान्वयन की विशेषताओं को दिखाया है ।

NavigableMapइंटरफ़ेस क्या है SortedMapपहली जगह में किया जाना चाहिए था। SortedMapतार्किक रूप से हटा दिया जाना चाहिए, लेकिन के रूप में कुछ 3rd पक्ष के मानचित्र कार्यान्वयन इंटरफ़ेस का उपयोग किया जा सकता है नहीं हो सकता।

जैसा कि आप इस तालिका में देख सकते हैं, केवल दो वर्ग SortedMap/ NavigableMapइंटरफेस लागू करते हैं :

ये दोनों कुंजी क्रम में रखते हैं, या तो उनके प्राकृतिक क्रम compareToसे Comparable( https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ Comparable.html ) इंटरफ़ेस) या आपके द्वारा Comparatorपास किए गए कार्यान्वयन से। इन दो वर्गों के बीच अंतर यह है कि एक दूसरे के, है ConcurrentSkipListMap, है धागा सुरक्षित , अत्यधिक समवर्ती

नीचे तालिका में Iteration ऑर्डर कॉलम भी देखें ।

  • जिस LinkedHashMapक्रम में उन्हें मूल रूप से डाला गया था, उसी क्रम से वर्ग अपनी प्रविष्टियाँ लौटाता है ।
  • EnumMapउस क्रम में प्रविष्टियाँ लौटाता है जिसके द्वारा कुंजी का एनम वर्ग परिभाषित किया गया है । उदाहरण के लिए, किस कर्मचारी का एक नक्शा सप्ताह के किस दिन को कवर कर रहा है ( Map< DayOfWeek , Person >) DayOfWeekजावा में निर्मित एनम वर्ग का उपयोग करता है । उस एनम को सोमवार पहले और रविवार आखिरी के साथ परिभाषित किया गया है। तो उस क्रम में एक पुनरावृत्त में प्रविष्टियाँ दिखाई देंगी।

अन्य छह कार्यान्वयन उस क्रम के बारे में कोई वादा नहीं करते हैं जिसमें वे अपनी प्रविष्टियों की रिपोर्ट करते हैं।

जावा 11 में मानचित्र कार्यान्वयन की तालिका, उनकी विशेषताओं की तुलना करते हुए


0

मैंने मूल्यों द्वारा मानचित्र को क्रमबद्ध करने के लिए सरल हैश मैप, लिंक की गई सूची और संग्रह का उपयोग किया है।

import java.util.*;
import java.util.Map.*;
public class Solution {

    public static void main(String[] args) {
        // create a simple hash map and insert some key-value pairs into it
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("Python", 3);
        map.put("C", 0);
        map.put("JavaScript", 4);
        map.put("C++", 1);
        map.put("Golang", 5);
        map.put("Java", 2);
        // Create a linked list from the above map entries
        List<Entry<String, Integer>> list = new LinkedList<Entry<String, Integer>>(map.entrySet());
        // sort the linked list using Collections.sort()
        Collections.sort(list, new Comparator<Entry<String, Integer>>(){
        @Override
         public int compare(Entry<String, Integer> m1, Entry<String, Integer> m2) {
        return m1.getValue().compareTo(m2.getValue());
        }
      });
      for(Entry<String, Integer> value: list) {
         System.out.println(value);
     }
   }
}

आउटपुट है:

C=0
C++=1
Java=2
Python=3
JavaScript=4
Golang=5
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.