2011-01-08 8 views
7

में कुंजी के रूप में int सरणी के साथ हैशटेबल मैं जावा में एक हैशटेबल बनाने की कोशिश कर रहा हूं जहां कुंजी int [] है, लेकिन यह काम नहीं कर रहा है। मैं एक छोटे से परीक्षण कार्यक्रम मेरी समस्या को दिखाने के लिए बना दिया है:जावा

public class test{ 
     public static void main(String[] args){ 
       int[] test0 = {1,1}; 
       int[] test1 = {1,1}; 
       Hashtable<int[], String> ht = new Hashtable<int[], String>(); 
       String s0 = "foo"; 

       ht.put(test0, s0); 

       System.out.println("the result from ht.get(test1)"); 
       System.out.println(ht.get(test1)); 
       System.out.println("the result from ht.get(test0)"); 
       System.out.println(ht.get(test0)); 
     } 
} 

मेरे इरादा है कि दोनों ht.get कैलेस ही परिणाम लौटना चाहिए, के बाद से दो सरणियों बराबर हैं, लेकिन वे नहीं है।

the result from ht.get(test1) 
null 
the result from ht.get(test0) 
foo 

मैं यहाँ कुछ कमी कर रहा हूँ या यह सिर्फ उपयोग करने के लिए असंभव है पूर्णांक [] एक hastable में कुंजी के रूप में: यहाँ कोड चलने से परिणाम है?

उत्तर

14

आप int [] को कुंजी के रूप में उपयोग कर सकते हैं, लेकिन यह वही सामग्री होना चाहिए, न कि केवल वही सामग्री हो। (जिसका अर्थ है कि यह वही नहीं करेगा जो आप चाहते हैं)

Arrays बराबर नहीं हैं() या एक ही हैशकोड() उनके सामग्री के आधार पर यदि वे एक ही सरणी हैं।

एकमात्र तरीका यह है कि आप ऐसा कर सकते हैं सूची < इंटीजर> अपनी int के लिए एक कुंजी या रैपर के रूप में [] उदा। TIntArrayList।

निम्नलिखित का प्रयास करें।

List<Integer> test0 = Arrays.asList(1,1); 
List<Integer> test1 = Arrays.asList(1,1); 
Map<List<Integer>, String> ht = new HashMap<List<Integer>, String>(); 

बीटीडब्ल्यू: हैशटेबल एक विरासत वर्ग आईएमएचओ है, इसे तब तक उपयोग न करें जब तक आपको यह नहीं करना पड़े।

+4

+1 सही उत्तर –

+3

सूचियां (आमतौर पर) उत्परिवर्तनीय भी होती हैं। महत्वपूर्ण अंतर यह है कि ['list.equals'] (http://download.oracle.com/javase/6/docs/api/java/util/List.html#equals%28java.lang.Object%29) और ['List.hashCode'] (http://download.oracle.com/javase/6/docs/api/java/util/List.html#hashCode%28%29) तत्व-वार समानता का उपयोग करने की आवश्यकता है। –

+0

@ मैथ्यू, अच्छा बिंदु।उत्परिवर्तन का उल्लेख हटा दिया गया। –

0

आप hashing से पहले सरणियों से बाहर तार बना सकते हैं एक सूची में लपेटकर के अलावा (जब तक कि सरणी की लंबाई निषेधात्मक लंबा है)

आप चुनना चाहिए उत्तरार्द्ध Arrays की एक स्थिर विधि यहाँ वर्णित नहीं है From java static Arrays class at http://download.oracle.com/javase/1.5.0/docs/api/java/util/Arrays.html#toString(int[])

h1.put(Arrays.toString(test1), s0); 

अब आप इस हैश सकता है, और बराबर सरणियों एक ही बात करने के लिए हैश होगा। आप कुंजी से सरणी को फिर से बनाने में सक्षम नहीं होंगे, हालांकि (जब तक जावा में eval का कोई प्रकार नहीं है?)




curiousities के लिए, यहाँ मेरे मूर्खता से अपने खुद के रोलिंग जब तक मैं उपरोक्त विधि पाया है:

public String intArrayToString(int[] x) 
{ 
    String ans = '['; 
    for(i = 0; i < size(x); i++) 
     ans += '' + i + ','; 
    return ans + ']'; 
} 

HashTable<String,String> h1 = new HashTable<String,String> h1; 
h1.put(intArrayToString(test1), s0); 

अगर वहाँ स्थिर toString है कि इस मैं माफी माँगता हूँ करता है किसी तरह का है। पीएस - क्या जावा ने फ़ंक्शन (और लैम्बडास) को कम किया है, फ़ोरैच लूप, या eval (आवश्यकता होने पर सरणी में कुंजियों को पुनर्निर्माण के लिए) अभी तक? वे इस समाधान अच्छे होगा ...

+0

हां, 'Arrays.toString' स्थिर विधि है। माफी स्वीकार की, कप्तान jon_darkstar। –

+0

हां आपने मुझे थोड़ा हराया = पी –

+0

स्ट्रिंग में सरणी को घुमाकर वह समाधान भी था जिसे मैंने अपने बारे में सोचा था, लेकिन मुझे हर बार तारों को बनाने के लिए अनजान उपर के विचार को पसंद नहीं आया हैशटेबल –

0

मूल कारण सरणी test0 और test1अलग hashCodes है। यदि 2 कुंजियों में अलग हैशकोड हैं, तो वे कभी भी समान नहीं हो सकते हैं।