2011-02-14 19 views
5

के साथ जावा संग्रह मैं 2 घटकों के साथ एक कुंजी के साथ हैश मैप को कार्यान्वित करना चाहता हूं। पूर्व।2 संग्रह

Pseudocode: 

Key = <Component1, Component2> 
CollName<Key, Val> coll = new CollName<Key, Val>; 

संग्रह में गति और आकार पर विचार करते हुए मैं जावा में इसे कैसे कार्यान्वित कर सकता हूं। धन्यवाद: डी

उत्तर

7

आप एक सहायक की जरूरत है (समग्र कुंजी) वर्ग है कि अपने दो चाबियाँ

public class CompositeKey<... , ...> { 
    ... component1; 
    ... component2; 

    // getter , setter, ... 

    // equals 

    // hashcode() 
} 

रखती है और फिर आप यह कुंजी के रूप में उपयोग कर सकते हैं:

CompositeKey cKey = new CompositeKey(1,2); 
Map x.put(cKey,val); 

यह करने के लिए यहाँ बहुत महत्वपूर्ण है एक अच्छी फैशन में equals() और hashCode() लागू करें। अधिकांश आईडीई आपकी मदद कर सकते हैं। हैशकोड के लिए महत्वपूर्ण है कि यह कुंजी के हैश टकराव को रोकने के लिए "अद्वितीय" मान देता है (यानी निरंतर मूल्य लौटाना सबसे खराब मामला है, क्योंकि सभी मान एक ही बाल्टी में समाप्त हो जाते हैं)। hashCode के कई प्रयोगों

hashcode = component1.hashCode() + 37* component2.hashCode(); 

आपको और अधिक जानकारी चाहते हैं, तो अपने साथ कुछ करना, किसी भी सीएस किताब कि एल्गोरिदम hashing बारे में बात करती बाहर खुदाई।

यदि आप दृढ़ता के लिए इसका उपयोग करना चाहते हैं, तो this blog post पर भी एक नज़र डालें।

+0

@Hieko: खोजक का उपयोग करके बनाना आसान है।क्या आप ऐसे स्रोत के बारे में जानते हैं जो सहायक वर्गों को बताता है क्योंकि मैं अवधारणा से परिचित नहीं हूं। –

+1

एक सहायक वर्ग इस तरह की एक विशेष अवधारणा नहीं है, यह केवल एक सामान्य वर्ग है जो आपके दो उपनिवेशों को लपेटती है और उन्हें एक के रूप में मानती है। अधिक विस्तृत कोड उदाहरण के लिए नीचे मेरा उदाहरण देखें। –

+0

@ हेको मुख्य समस्या यह है कि आप बराबर और हैशकोड को सही तरीके से कैसे कार्यान्वित करते हैं। –

2

आप दो कुंजी के साथ सीधे नक्शा नहीं बना सकते हैं, हालांकि आप दोनों को जोड़ सकते हैं।

सबसे आसान तरीका है उन्हें एक स्ट्रिंग में क्रमबद्ध करना और उन्हें गठबंधन करना।

String key = obj1.toString() + "-" + obj2.toString(); 
myMap.put(key, myValue); 

वस्तुओं मानते हुए आसानी से एक स्ट्रिंग है अद्वितीय होगा धारावाहिक जा सकता है।

यदि ऐसा नहीं है, तो एक रैपर ऑब्जेक्ट बनाना आपका सबसे अच्छा विकल्प है। आपको उस ऑब्जेक्ट को परिभाषित करने की आवश्यकता होगी जो बराबर() और हैशकोड() विधि को ओवरराइड करता है।

एक मोटा उदाहरण

class CombinedKey{ 
    private MyClass object1; 
    private MyClass object2; 

    public CombinedKey(MyClass object1, MyClass object2){ 
     this.object1 = object1; 
     this.object2 = object2; 
    } 
    public int hashCode(){ 
     return object1.hashCode() + object2.hashCode(); 
    } 

    @Override 
    public Boolean equals(Object otherObject){ 
     if(otherObject == null || otherObject.getObject1() == null) return false; 
     return object1.equals(otherObject.getObject1()) && object2.equals(otherObject.getObject2(); 
    } 

    public MyClass getObject1() { return object1; } 
    public MyClass getObject2() { return object2; } 

} 

(तुम भी तो यह अन्य परिदृश्यों में पुन: उपयोग किया जा सकता है इस वर्ग को परिभाषित करने के जेनेरिक्स उपयोग करने पर विचार करना चाह सकते हैं) के रूप में

उपयोग:

Map<CombinedKey, Object> myMap = new HashMap<CombinedKey, Object>(); 
myMap.put(new CombinedKey(obj1, obj2), value); 
+3

आपके उत्तर से सहमत हैं। विधि को बराबर() हस्ताक्षर नोट करें, यह ऑब्जेक्ट क्लास से ओवरराइड नहीं है। –

+1

डेटाबेस में समग्र कुंजी के बारे में मुझे याद दिलाता है। –

+2

ध्यान दें कि एक कीपैयर (ए, बी) के लिए यह कार्यान्वयन उसी हैशकोड को (बी, ए) के रूप में देता है जो हैश टकराव बनाता है, जो प्रदर्शन को सीमित कर सकता है (कुछ हद तक)। –

0

यह HashMap का सामान्य उपयोग है, बिंदु यह है कि आपको परिभाषित करना होगा (ओवरराइड) बराबर() और हैशकोड() कक्षा Key में ठीक से।

1

अभी तक Google Guava उत्तर नहीं मिला, इसलिए सोचा कि मैं इसे इंगित करूंगा: मैं Table का उपयोग करूंगा।

0

CompositKey/Pair/Tuple का उपयोग करने के लिए एक अच्छा विकल्प List का उपयोग करना है। List कार्यान्वयन में पहले से ही एक उचित परिभाषित equals() और hashCode() है और Arrays.asList()

संबंधित मुद्दे