HashMap और कुंजी के रूप में int


104

मैं एक HashMap बनाने की कोशिश कर रहा हूं जिसमें मानों के रूप में कुंजी और ऑब्जेक्ट के रूप में पूर्णांक होगा।

मेरा वाक्यविन्यास है:

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

हालाँकि, त्रुटि वापस आ गई है - टोकन "int" पर सिंटैक्स त्रुटि, इस टोकन के बाद अपेक्षित आयाम - मुझे समझ में नहीं आता कि मुझे एक आयाम क्यों जोड़ना चाहिए (यानी: सरणी में int बनाना) क्योंकि मुझे केवल एक अंक संग्रहीत करने की आवश्यकता है कुंजी के रूप में।

मैं क्या कर सकता था?

अग्रिम में धन्यवाद! :)


14
HashMapआदिम नहीं संभालता है, बस वस्तुओं।
मेंनो

संबंधित एसओ प्रश्न , लेकिन intमूल्य होने के साथ , कुंजी नहीं।
साइबरक्स

5
Integerइसके बजाय उपयोग करें ।
हॉट लाइक्स

क्या यह इंटोबर्स के लिए ऑटोबॉक्स इंट से बेहतर है या केवल डेटा को स्ट्रिंग के रूप में स्टोर करना है, जो अधिक आरामदायक है?
Marcin Erbel

जवाबों:


25

आप एक आदिम का उपयोग नहीं कर सकते क्योंकि HashMap कुंजी के लिए आंतरिक रूप से ऑब्जेक्ट का उपयोग करता है। तो आप केवल एक ऑब्जेक्ट का उपयोग कर सकते हैं जो ऑब्जेक्ट से विरासत में मिला है (जो कि कोई ऑब्जेक्ट है)।

हाशप में यह फंक्शन डाला () है और जैसा कि आप देख सकते हैं यह K के लिए ऑब्जेक्ट का उपयोग करता है:

public V put(K key, V value) {
    if (key == null)
        return putForNullKey(value);
    int hash = hash(key);
    int i = indexFor(hash, table.length);
    for (Entry<K,V> e = table[i]; e != null; e = e.next) {
        Object k;
        if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
            V oldValue = e.value;
            e.value = value;
            e.recordAccess(this);
            return oldValue;
        }
    }

    modCount++;
    addEntry(hash, key, value, i);
    return null;
}

अभिव्यक्ति "k = e.key" को स्पष्ट करना चाहिए।

मैं सुझाव देता हूं कि इंटेगर और ऑटोबॉक्सिंग जैसे रैपर का उपयोग करें।


137

Integerइसके बजाय उपयोग करें ।

HashMap<Integer, MyObject> myMap = new HashMap<Integer, MyObject>();

जावा स्वचालित रूप intसे Integerवस्तुओं के लिए आपके आदिम मूल्यों को स्वत: स्फूर्त करेगा ।

ओरेकल जावा दस्तावेज़ों से ऑटोबॉक्सिंग के बारे में और पढ़ें ।


10
उसे एक वर्ग का नाम भी नहीं देना चाहिएmyObject
एडम जेंट

@ एडमजेंट करेक्ट। सभी श्रेणी के नाम राजधानियों से शुरू होने चाहिए, मैंने अनुशंसित कोड को सही किया।
gaborsch

3
मुझे पता है आप जानते हैं :) मैं सिर्फ यह सुनिश्चित करना चाहता हूं कि ओपी जानता / सीखता है। सभी के लिए मुझे पता है कि वह टाइप पैरामीटर में एक चर नाम रख सकता था।
एडम जेंट

1
बस एक त्वरित थोड़ा ध्यान दें, इसका इस्तेमाल करने के लिए बेहतर है ArrayMapया SimpleArrayMapएंड्रॉयड पर स्मृति और वृद्धि प्रदर्शन (बचाने के लिए अधिक जानकारी )
नूह हुपर्ट

42

हर कोई जो एंड्रॉइड डिवाइसों के लिए जावा को कोड करता है और यहां समाप्त होता है: SparseArrayबेहतर प्रदर्शन के लिए उपयोग करें ;

private final SparseArray<myObject> myMap = new SparseArray<myObject>();

इसके साथ आप Integer की जगह int का उपयोग कर सकते हैं जैसे;

int newPos = 3;

myMap.put(newPos, newObject);
myMap.get(newPos);

7
याद रखें कि SparseArray हैशमाप की तुलना में धीमी है, लेकिन अधिक स्मृति कुशल है। इसलिए, बड़े डेटा सेट पर इसका उपयोग न करें।
TpoM6oH

कैसे धीमी गति से बेहतर प्रदर्शन के लिए SparseArray का उपयोग किया जाता है? मेरे एंड्रॉइड गेम में कौन सा उपयोग करना है
स्नेक

@Snake SparseArrayयदि आप मेमोरी बॉक्सिंग और अनबॉक्सिंग इनट्स का एक गुच्छा आवंटित करते हैं जैसा कि आप एक के साथ करेंगे HashMap, तो vm को कचरा संग्रहण के लिए जल्द ही रोकना होगा। यह महत्वपूर्ण है अगर आप बार-बार और जल्दी से कुछ करने की कोशिश कर रहे हैं।
जॉन

1
प्रविष्टि के उस जटिलता याद में SparseArrayहै हे (एन) ( HashMapहै हे (1) )। तत्वों की संख्या बड़ी होने पर यह महत्वपूर्ण है। ऐसे एरे की शुरुआत में प्रविष्टि बहुत धीमी है।
व्लादिमीर पेट्राकोविच

1
@ M.kazemAkhgary बिल्कुल नहीं। शुरू में सम्मिलन के लिए (नहीं ) put()लेता है क्योंकि यह स्थिति पाता है और फिर सभी निम्नलिखित तत्वों को स्थानांतरित करता है। स्वयं वास्तव में लेता है , लेकिन हटाने के बाद तत्वों के माध्यम से अगले सम्मिलन या पुनरावृत्ति को कचरा संग्रह की आवश्यकता होती है । O(n)n log ndelete()O(log n)O(n)
व्लादिमीर पेट्राकोविच


4

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

इस प्रकार जब int को Integer में autoboxed किया जाता है, तो Hashmap Integer ऑब्जेक्ट पर बराबर () विधि कह सकता है ।

इसीलिए, आपको int के बजाय Integer का उपयोग करना चाहिए। मेरा मतलब है कि हैशमैप एक कुंजी के रूप में इंट डालते समय एक त्रुटि फेंकता है (फेंकी गई त्रुटि का अर्थ नहीं जानता)

और अगर आपको लगता है कि, आप मुख्य के रूप में एक आदिम बनाकर मानचित्र के प्रदर्शन को तेज़ कर सकते हैं, तो एक लाइब्रेरी है जिसे FastUtil कहा जाता है जिसमें एक कुंजी के रूप में int प्रकार के साथ एक मानचित्र कार्यान्वयन होता है।

इस वजह से यह हशमप की तुलना में बहुत तेज है


1
नहीं है, आदिम प्रकार की अनुमति नहीं दे के लिए मुख्य कारण है प्रकार विलोपन प्रभावी रूप से चला है कि जावा में, Map<Integer, String>में Map<Object, Object>संकलन के दौरान। BTW, IdentityHashMap है जो ==समानता की जांच के लिए ऑपरेटर का उपयोग करता है , जो अभी भी आदिम प्रकार की अनुमति नहीं देता है।
योरी एन।

3

HashMap दलीलों के रूप में आदिम डेटा प्रकारों की अनुमति नहीं देता है। यह केवल वस्तुओं को स्वीकार कर सकता है

HashMap<int, myObject> myMap = new HashMap<int, myObject>();

काम नहीं करेगा।

आपको घोषणा को बदलना होगा

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

तो जब आप निम्न कार्य करते हैं

myMap.put(2,myObject);

आदिम डेटा प्रकार एक पूर्णांक वस्तु के लिए स्वत: निर्मित है।

8 (int) === boxing ===> 8 (Integer)

आप यहाँ ऑटोबॉक्सिंग पर अधिक पढ़ सकते हैं http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html


3

यदि आप Android में कोड करते हैं, तो SparseArray है , ऑब्जेक्ट के लिए पूर्णांक मैपिंग।


1

आदिम प्रकार के रूप में int का उपयोग न करें

HashMap<Integer, myObject> myMap = new HashMap<Integer, myObject>();

मेरे पास HashMap <Integer, MyObject> myMap = new HashMap <Integer, MyObject> () है; लेकिन अच्छा जवाब प्रदर्शित करने के लिए> और <के साथ मेरी समस्या को प्रदर्शित करना
franki3xe

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


0

मुझे समझ नहीं आ रहा है कि मुझे एक आयाम क्यों जोड़ना चाहिए (अर्थात: किसी सरणी में int बनाना) क्योंकि मुझे केवल एक अंक को कुंजी के रूप में संग्रहीत करने की आवश्यकता है।

एक सरणी भी एक वस्तु है, इसलिए HashMap<int[], MyObject>एक वैध निर्माण है जो कुंजियों के रूप में int सरण का उपयोग करता है।

कंपाइलर को यह नहीं पता है कि आपको क्या चाहिए या आपको क्या चाहिए, यह सिर्फ एक भाषा निर्माण को देखता है जो लगभग सही है, और चेतावनी देता है कि इसके पूरी तरह से सही होने के लिए क्या गायब है।


1
इससे सावधान रहें, किसी सरणी का हैश मान उसकी सामग्री से संबंधित नहीं है, इसलिए एक ही सामग्री के साथ दो सरणियों को एक अलग मान के लिए हैश कर सकता है जो इसे बहुत खराब कुंजी बनाता है।
john16384

0

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

import org.eclipse.collections.impl.map.mutable.primitive.IntObjectHashMap;

public class Check {
    public static void main(String[] args) {
        IntObjectHashMap map = new IntObjectHashMap();

        map.put(5,"It works");
        map.put(6,"without");
        map.put(7,"boxing!");

        System.out.println(map.get(5));
        System.out.println(map.get(6));
        System.out.println(map.get(7));
    }
}

IntObjectHashMap के ऊपर इस उदाहरण में ।

जैसा कि आपको int-> ऑब्जेक्ट मैपिंग की YourObjectType[]आवश्यकता है List<YourObjectType>, इंडेक्स द्वारा सरणी या एक्सेस मानों के उपयोग पर भी विचार करें , जैसा कि मानचित्र है, स्वभाव से, इंडेक्स के साथ इंट प्रकार के साथ एक सहयोगी सरणी।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.