2014-11-18 5 views
7

नमस्ते मैं सोच रहा हूं कि यदि आपके पास जिस ऑब्जेक्ट की तलाश है, उसके लिए हैशकोड है तो हैशसेट को सीधे एक्सेस करना संभव है, हैश मैप में एक हैशकोड का उपयोग करने की तरह।हैशकोड का उपयोग कर हैशसेट को सीधे एक्सेस करना? (जावा)

मैं कल्पना इसे इस तरह एक तरह से कुछ काम कर सकते हैं:

MyObject object1 = new MyObject(1); 

Set<MyObject> MyHashSet = new HashSet<MyObject>(); 

MyHashSet.add(object1) 

int hash = object1.getHashCode 

MyObject object2 = MyHashSet[hash]??? 

धन्यवाद!

संपादित करें: उत्तर के लिए धन्यवाद। ठीक है, मैं समझता हूं कि मैं हैशसेट के अनुबंध को थोड़ा सा धक्का दे सकता हूं, लेकिन इस विशेष परियोजना समानता के लिए हैशकोड द्वारा पूरी तरह से निर्धारित किया गया है और मुझे यह सुनिश्चित करने के लिए पता है कि हैशकोड/हैशबकेट प्रति केवल एक वस्तु होगी। हैश मैप का उपयोग करने के लिए मैं बहुत अनिच्छुक था क्योंकि मुझे इंटीग्रेट ऑब्जेक्ट्स के साथ मैपिंग करने वाले आदिम इन्ट्स को कन्वर्ट करने की आवश्यकता होगी क्योंकि हैश मैप केवल ऑब्जेक्ट्स के रूप में ऑब्जेक्ट्स लेता है, और मैं भी चिंतित हूं कि इससे प्रदर्शन प्रभावित हो सकता है। क्या ऐसा कुछ और है जो मैं कुछ ऐसा करने के लिए कर सकता था?

+0

नहीं, यह संभव नहीं है। तुमने ऐसा क्यों करना चाहोगे? ऐसा लगता है कि आप एक नक्शा चाहते हैं। –

+2

ऐसी कोई सार्वजनिक एपीआई नहीं। और यहां तक ​​कि अगर वहां था, तो यह हैश कोड टकराव के रूप में कई वस्तुओं को वापस कर सकता है। – Thilo

+0

ऑब्जेक्ट को इस तरह से प्राप्त करना संभव नहीं है। यह समझ में आता है क्योंकि दो अलग-अलग ऑब्जेक्ट्स में एक ही हैशकोड हो सकता है लेकिन यह बराबर नहीं हो सकता है। हैशसेट आंतरिक रूप से बराबर विधि के साथ दो ऑब्जेक्ट्स की तुलना करता है यदि उनके हैशकोड मैचों। – BatScream

उत्तर

2

HashSet का सामान्य कार्यान्वयन HashMap द्वारा समर्थित (बल्कि आलसी) है, इसलिए HashMap से बचने के आपके प्रयास शायद हार गए हैं।

आधार यह है कि समय से पहले अनुकूलन सब बुराई की जड़ है, मैं आप शुरू में एक HashMap का उपयोग करें और यदि बॉक्सिंग/करने के लिए और Integer से int की unboxing भूमि के ऊपर वास्तव में एक समस्या है आप को लागू करने के लिए है (या मिल जाएगा सुझाव है) तुलना के लिए आदिम int एस का उपयोग करके एक हस्तशिल्प HashSet। मानक जावा लाइब्रेरी वास्तव में मुक्केबाजी/अनबॉक्सिंग लागतों से खुद को चिंता नहीं करना चाहती है। पूरी भाषा ने बहुत पहले सादगी में काफी लाभ के लिए उस प्रदर्शन मुद्दे को बेचा। ध्यान दें कि इन दिनों (2004 से!) भाषा स्वचालित रूप से बक्से और अनबॉक्स हैं जो बताती है कि "आपको इस बारे में चिंता करने की आवश्यकता नहीं है" नीति। ज्यादातर मामलों में यह सही है।

मुझे नहीं पता कि आपके HashKeyedSet को कैसे समृद्ध रूप से प्रदर्शित किया गया है, लेकिन मूलभूत हैश-टेबल वास्तव में बहुत कठिन नहीं है।

0

यह संभव नहीं है क्योंकि HashSet एक वस्तु है और इस तरह कोई सार्वजनिक एपीआई नहीं है। इसके अलावा कई ऑब्जेक्ट्स में एक ही हैशकोड हो सकता है लेकिन ऑब्जेक्ट्स अलग-अलग हो सकते हैं।

अंत में केवल myArray[<index>] वाक्यविन्यास का उपयोग करके सरणी का उपयोग किया जा सकता है।

2

HashSet आंतरिक रूप से HashMap द्वारा समर्थित है, जो दुर्भाग्य से इस प्रश्न के लिए सार्वजनिक एपीआई के माध्यम से अनुपलब्ध है। हालांकि, हम आंतरिक नक्शा करने के लिए पहुँच प्राप्त करने के प्रतिबिंब का उपयोग कर सकते हैं और फिर एक समान hashCode के साथ एक चाबी मिल:

private static <E> E getFromHashCode(final int hashcode, HashSet<E> set) throws Exception { 
    // reflection stuff 
    Field field = set.getClass().getDeclaredField("map"); 
    field.setAccessible(true); 

    // get the internal map 
    @SuppressWarnings("unchecked") 
    Map<E, Object> interalMap = (Map<E, Object>) (field.get(set)); 

    // attempt to find a key with an identical hashcode 
    for (E elem : interalMap.keySet()) { 
     if (elem.hashCode() == hashcode) return elem; 
    } 
    return null; 
} 

एक उदाहरण में प्रयुक्त:

HashSet<String> set = new HashSet<>(); 
set.add("foo"); set.add("bar"); set.add("qux"); 

int hashcode = "qux".hashCode(); 

System.out.println(getFromHashCode(hashcode, set)); 

आउटपुट:

qux 
+0

धन्यवाद! यह करने का एक शानदार तरीका है, हालांकि इसे लश के साथ हैशसेट के माध्यम से खोजना आवश्यक है, मुझे पता है कि मैं जो पूछ रहा हूं वह अब असंभव है, लेकिन मैंने सोचा कि उस हैशकोड पर सीधे डेटा प्राप्त करने का कोई तरीका हो सकता है, जैसे यह एक सूची या कुछ है। – Kode47

+0

मुझे संदेह है कि यह लगातार प्रतिबिंब हैकर के साथ लगातार समय में करना संभव है, क्योंकि 'हैश मैप' आपको सार्वजनिक एपीआई के माध्यम से तालिका में किसी विशिष्ट इंडेक्स पर बाल्टी नहीं देता है। – August

0

आप आसानी से कोड लिख सकते हैं जो प्रतिबिंब का उपयोग करके हैशसेट कार्यान्वयन की आंतरिक डेटा संरचनाओं तक सीधे पहुंच जाएगा। बेशक, आपका कोड उस विशेष जेवीएम के कार्यान्वयन विवरण पर निर्भर करेगा जिसे आप कोडिंग कर रहे हैं। आप सुरक्षा प्रबंधक (यदि कोई हो) की बाधाओं के अधीन भी होंगे।

हैशसेट का एक सामान्य कार्यान्वयन हैश मैप का उपयोग आंतरिक डेटा संरचना के रूप में करता है। हैश मैप में एक सरणी है, जिसे सरणी में एक इंडेक्स में मैप किए गए कुंजी के हैशकोड द्वारा अनुक्रमित किया गया है। हैशकोड मैपिंग फ़ंक्शन कार्यान्वयन में गैर-सार्वजनिक विधियों को कॉल करके उपलब्ध है - आपको स्रोत कोड पढ़ना होगा और इसे समझना होगा। एक बार जब आप दाएं बाल्टी तक पहुंच जाएंगे, तो आपको बाल्टी में सही प्रविष्टि (equals का उपयोग करके) ढूंढने की आवश्यकता होगी।

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