जावा क्लास जो नक्शा लागू करता है और प्रविष्टि क्रम रखता है?


463

मैं जावा में एक वर्ग की तलाश कर रहा हूं, जिसमें की-वैल्यू एसोसिएशन है, लेकिन हैश का उपयोग किए बिना। यहाँ मैं वर्तमान में क्या कर रहा हूँ:

  1. के मान जोड़ें Hashtable
  2. के लिए एक पुनरावृत्ति प्राप्त करें Hashtable.entrySet()
  3. सभी मूल्यों के माध्यम से परिवर्तन करें और:
    1. Map.Entryपुनरावृति के लिए प्राप्त करें ।
    2. Moduleमूल्य के आधार पर प्रकार की वस्तु (एक कस्टम वर्ग) बनाएँ ।
    3. एक JPanel में वर्ग जोड़ें।
  4. पैनल दिखाएं।

इसके साथ समस्या यह है कि मुझे उस आदेश पर नियंत्रण नहीं है जो मुझे मूल्यों को वापस मिलता है, इसलिए मैं दिए गए क्रम में मूल्यों को प्रदर्शित नहीं कर सकता (बिना आदेश के हार्ड-कोडिंग के)।

मैं इसके लिए ArrayListया का उपयोग करूंगा Vector, लेकिन बाद में कोड में मुझे Moduleकिसी दिए गए कुंजी के लिए ऑब्जेक्ट को हथियाने की आवश्यकता है , जिसे मैं ArrayListया के साथ नहीं कर सकता Vector

क्या किसी को एक स्वतंत्र / ओपन-सोर्स जावा वर्ग का पता है जो ऐसा करेगा, या Hashtableजब वे जोड़े गए थे, तो किसी आधार पर मूल्यों को प्राप्त करने का एक तरीका है ?

धन्यवाद!


1
आपको एंट्रीसेट / map.entry का उपयोग करने की आवश्यकता नहीं है। आप हैशटेबल के रूप में हैशटेब का उपयोग करके या हैशटेब का उपयोग करके।
जॉन गार्डनर

5
मैंने शीर्षक बदलने के लिए स्वतंत्रता ली, क्योंकि हैश का उपयोग नहीं करना वास्तव में समस्या नहीं है, लेकिन सम्मिलन क्रम को बनाए रखना है।
जोकिम सॉर

जवाबों:


734

मैं एक LinkedHashMapया एक सुझाव देता हूं TreeMap। A LinkedHashMapउन कुंजियों को रखता है जिस क्रम में उन्हें डाला गया था, जबकि एक TreeMapको तत्वों Comparatorके प्राकृतिक Comparableक्रम के माध्यम से क्रमबद्ध रखा जाता है ।

चूंकि इसमें तत्वों को क्रमबद्ध नहीं रखना है, इसलिए LinkedHashMapअधिकांश मामलों के लिए तेज़ होना चाहिए;TreeMapहै O(log n)के लिए प्रदर्शन containsKey, get, put, और remove, Javadocs के अनुसार, जबकि LinkedHashMapहै O(1)प्रत्येक के लिए।

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


2
यह मेरे लिए काम नहीं करेगा क्योंकि, javadocs के अनुसार, यह केवल ऑर्डर किए गए मान देता है (मूल्यों के माध्यम से) (कॉल)। क्या ऑर्डर किए गए Map.Entry इंस्टेंसेस पाने का कोई तरीका है?
कोरी केंडल

1
@CoryKendall: क्या TreeMap काम नहीं करता है? इसे मानों द्वारा नहीं, कुंजी द्वारा क्रमबद्ध किया जाना चाहिए।
माइकल मायर्स

1
मेरी गलती, मुझे लगा कि सेट्स अनसोल्ड थे।
कोरी केंडल

61
कृपया ध्यान दें: ट्रीपाउप की छँटाई कुंजियों के प्राकृतिक क्रम पर आधारित है: "मानचित्र को उसकी कुंजियों के प्राकृतिक क्रम के अनुसार क्रमबद्ध किया जाता है"। LinkedHashMap बीआईजी इन्सर्ट क्रम को क्रमबद्ध करता है। बड़ा अंतर!
जोप वैन रायज

3
@AlexR: यह केवल सच है अगर LinkedHashMap विशेष निर्माता का उपयोग करके बनाया गया था जो उस उद्देश्य के लिए प्रदान किया गया है। डिफ़ॉल्ट रूप से, पुनरावृत्ति प्रविष्टि क्रम में है।
माइकल मायर्स

22

LinkedHashMap तत्वों को उस क्रम में वापस कर देगा, जब वे मैप में डाले गए थे जब आप मैप के कीसेट (), एंट्रीसेट () या मान () पर ओवररेट करते हैं।

Map<String, String> map = new LinkedHashMap<String, String>();

map.put("id", "1");
map.put("name", "rohan");
map.put("age", "26");

for (Map.Entry<String, String> entry : map.entrySet()) {
    System.out.println(entry.getKey() + " = " + entry.getValue());
}

यह उन तत्वों को प्रिंट करेगा जिस क्रम में उन्हें मानचित्र में रखा गया था:

id = 1
name = rohan 
age = 26 

16

यदि कोई अपरिवर्तनीय मानचित्र आपकी आवश्यकताओं के अनुरूप है तो Google द्वारा एक पुस्तकालय है जिसे अमरुद कहा जाता है ( अमरूद के प्रश्न भी देखें )

अमरूद विश्वसनीय उपयोगकर्ता-निर्दिष्ट पुनरावृत्ति क्रम के साथ एक इम्यूटेबल मैप प्रदान करता है । इस ImmutableMap में O के लिए O (1) प्रदर्शन है, प्राप्त करें। स्पष्ट रूप से रखा और हटाए जाने का समर्थन नहीं किया जाता है।

ImmutableMap ऑब्जेक्ट्स () और copyOf () या बिल्डर ऑब्जेक्ट के सुरुचिपूर्ण स्थिर सुविधा विधियों का उपयोग करके निर्मित किए जाते हैं ।


6

आप Map(तेजी से देखने के लिए) और List(आदेश के लिए ) बनाए रख सकते हैं, लेकिन LinkedHashMapसबसे सरल हो सकता है। आप एक SortedMapउदाहरण के लिए भी कोशिश कर सकते हैं TreeMap, जो आपके पास कोई भी आदेश है।


1

मुझे नहीं पता कि यह ओपनसोर्स है या नहीं, लेकिन थोड़ी सी गुगली के बाद, मुझे ArrayList का उपयोग करके मैप का यह कार्यान्वयन मिला । यह पूर्व-1.5 जावा लगता है, इसलिए आप इसे सामान्य बनाना चाहते हैं, जो आसान होना चाहिए। ध्यान दें कि इस कार्यान्वयन में O (N) एक्सेस है, लेकिन यह समस्या नहीं होनी चाहिए यदि आप अपने JPanel में सैकड़ों विजेट नहीं जोड़ते हैं, जो आपको वैसे भी नहीं होना चाहिए।



1

जब भी मुझे समय से पहले जानी जाने वाली चीजों के प्राकृतिक क्रम को बनाए रखने की आवश्यकता होती है, मैं एक EnumMap का उपयोग करता हूं

कुंजियाँ enums होंगी और आप किसी भी क्रम में सम्मिलित कर सकते हैं जो आप चाहते हैं लेकिन जब आप इसे पुनरावृत्त करते हैं तो यह enum क्रम (प्राकृतिक क्रम) में पुनरावृति करेगा।

EnumMap का उपयोग करते समय भी कोई टकराव नहीं होना चाहिए जो अधिक कुशल हो सकता है।

मुझे वास्तव में पता चला है कि enumMap का उपयोग स्वच्छ पठनीय कोड के लिए करता है। यहाँ एक उदाहरण है


1

आप LinkedHashMap का उपयोग मानचित्र में मुख्य प्रविष्टि क्रम में कर सकते हैं

Java LinkedHashMap वर्ग के बारे में महत्वपूर्ण बिंदु हैं:

  1. इसमें केवल तत्व होते हैं।
  2. LinkedHashMap में कुंजी के आधार पर मान शामिल हैं। इसमें एक नल कुंजी और कई नल मान हो सकते हैं। 4. यह HashMap के समान है, इसके बजाय प्रविष्टि क्रम बनाए रखता है

    public class LinkedHashMap<K,V> extends HashMap<K,V> implements Map<K,V> 

लेकिन यदि आप उपयोगकर्ता द्वारा परिभाषित ऑब्जेक्ट या किसी भी आदिम डेटा प्रकार कुंजी का उपयोग करके मानचित्र में सॉर्ट मान चाहते हैं तो आपको TreeMap का उपयोग करना चाहिए। अधिक जानकारी के लिए, इस लिंक को देखें


0

या तो आप उपयोग कर सकते हैं LinkedHashMap<K, V>या आप अपने खुद के CustomMap को लागू कर सकते हैं जो प्रविष्टि क्रम बनाए रखता है।

आप CustomHashMapनिम्नलिखित सुविधाओं के साथ निम्नलिखित का उपयोग कर सकते हैं :

  • आंतरिक रूप से LinkedHashMap का उपयोग करके प्रविष्टि क्रम बनाए रखा जाता है।
  • के साथ की nullरिक्त स्ट्रिंग्स के की अनुमति नहीं है।
  • एक बार मूल्य के साथ कुंजी बनाने के बाद, हम इसके मूल्य को ओवरराइड नहीं कर रहे हैं।

HashMapबनाम LinkedHashMapबनामCustomHashMap

interface CustomMap<K, V> extends Map<K, V> {
    public boolean insertionRule(K key, V value);
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public class CustomHashMap<K, V> implements CustomMap<K, V> {
    private Map<K, V> entryMap;
    // SET: Adds the specified element to this set if it is not already present.
    private Set<K> entrySet;

    public CustomHashMap() {
        super();
        entryMap = new LinkedHashMap<K, V>();
        entrySet = new HashSet();
    }

    @Override
    public boolean insertionRule(K key, V value) {
        // KEY as null and EMPTY String is not allowed.
        if (key == null || (key instanceof String && ((String) key).trim().equals("") ) ) {
            return false;
        }

        // If key already available then, we are not overriding its value.
        if (entrySet.contains(key)) { // Then override its value, but we are not allowing
            return false;
        } else { // Add the entry
            entrySet.add(key);
            entryMap.put(key, value);
            return true;
        }
    }
    public V put(K key, V value) {
        V oldValue = entryMap.get(key);
        insertionRule(key, value);
        return oldValue;
    }
    public void putAll(Map<? extends K, ? extends V> t) {
        for (Iterator i = t.keySet().iterator(); i.hasNext();) {
            K key = (K) i.next();
            insertionRule(key, t.get(key));
        }
    }

    public void clear() {
        entryMap.clear();
        entrySet.clear();
    }
    public boolean containsKey(Object key) {
        return entryMap.containsKey(key);
    }
    public boolean containsValue(Object value) {
        return entryMap.containsValue(value);
    }
    public Set entrySet() {
        return entryMap.entrySet();
    }
    public boolean equals(Object o) {
        return entryMap.equals(o);
    }
    public V get(Object key) {
        return entryMap.get(key);
    }
    public int hashCode() {
        return entryMap.hashCode();
    }
    public boolean isEmpty() {
        return entryMap.isEmpty();
    }
    public Set keySet() {
        return entrySet;
    }
    public V remove(Object key) {
        entrySet.remove(key);
        return entryMap.remove(key);
    }
    public int size() {
        return entryMap.size();
    }
    public Collection values() {
        return entryMap.values();
    }
}

का उपयोग CustomHashMap:

public static void main(String[] args) {
    System.out.println("== LinkedHashMap ==");
    Map<Object, String> map2 = new LinkedHashMap<Object, String>();
    addData(map2);

    System.out.println("== CustomHashMap ==");
    Map<Object, String> map = new CustomHashMap<Object, String>();
    addData(map);
}
public static void addData(Map<Object, String> map) {
    map.put(null, "1");
    map.put("name", "Yash");
    map.put("1", "1 - Str");
    map.put("1", "2 - Str"); // Overriding value
    map.put("", "1"); // Empty String
    map.put(" ", "1"); // Empty String
    map.put(1, "Int");
    map.put(null, "2"); // Null

    for (Map.Entry<Object, String> entry : map.entrySet()) {
        System.out.println(entry.getKey() + " = " + entry.getValue());
    }
}

ओ / पी:

== LinkedHashMap == | == CustomHashMap ==
null = 2            | name = Yash
name = Yash         | 1 = 1 - Str
1 = 2 - Str         | 1 = Int
 = 1                |
  = 1               |
1 = Int             |

यदि आप जानते हैं कि कुंजी तय हो गई है तो आप EnumMap का उपयोग कर सकते हैं। मान प्राप्त करें गुण / XML फ़ाइलें

पूर्व:

enum ORACLE {
    IP, URL, USER_NAME, PASSWORD, DB_Name;
}

EnumMap<ORACLE, String> props = new EnumMap<ORACLE, String>(ORACLE.class);
props.put(ORACLE.IP, "127.0.0.1");
props.put(ORACLE.URL, "...");
props.put(ORACLE.USER_NAME, "Scott");
props.put(ORACLE.PASSWORD, "Tiget");
props.put(ORACLE.DB_Name, "MyDB");
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.