2010-06-15 8 views
6

जावा में मैं एक ही मान पर एकाधिक कुंजी मैप करने का एक तरीका ढूंढ रहा हूं। मान लीजिए कि मैं, "y" और मूल्यों के रूप में "Z" के रूप में इस संख्या 0-9 कुंजी के रूप में, और "x" करते हैं:जावा डेटास्ट्रक्चर एक ही मान पर एकाधिक कुंजियों को मैप करने के लिए

0->y 
1->y 
2->y 
3->x 
4->x 
5->y 
6->z 
7->y 
8->z 
9->z 

अब एक्स, वाई और जेड बहुत लंबा तार कर रहे हैं, और मैं लाखों चाबियाँ इसलिए मैं स्ट्रिंग को कई बार स्टोर नहीं कर सकता। आप इसके बारे में कैसे जाएंगे?

एक विचार जो मैंने दो सरणी बनाने के लिए किया था: कुंजी के लिए एक कृत्रिम दूसरा उत्पन्न होता है जिसके लिए मूल कुंजी मैप की जाती है और जो कि अन्य सरणी में वास्तविक मानों की कुंजी होती है। इस तरह मूल्यों केवल मूल्यों के लिए एक बार जमा हो जाती है और मूल कुंजी अभी भी परोक्ष रूप से मैप किया जा सकता:

0->k1 
1->k1 
2->k1 
3->k2 
4->k2 
5->k1 
6->k3 
7->k1 
8->k3 
9->k3 

k1->y 
k2->x 
k3->z 

प्रश्न हालांकि: इस के लिए एक बेहतर डेटा संरचना है?

उत्तर

19

किसी भी Map<Integer,String> करना होगा - आप केवल स्ट्रिंग, नहीं इसकी एक प्रति के लिए एक संदर्भ भंडारण कर रहे हैं, तो यह कोई फर्क नहीं पड़ता कि इसमें कितना समय है।

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

+0

यह समझ में आता है। धन्यवाद। 'इंटर्न() ' – eikes

+3

+1, पर्याप्त मेला। मेरे पास वास्तव में एक पेपर लिखने का समय नहीं है इसलिए मैंने अभी टिप्पणी हटा दी है। –

+0

पीट के लिए –

1

मैं वास्तव में प्रश्न को समझ नहीं पा रहा हूं। यदि आपके पास स्ट्रिंग्स की एक सरणी है: String[] arr तो बस एक ही ऑब्जेक्ट पर अलग-अलग इंडेक्स सेट करें - उर्फ ​​संदर्भों को समान बनाते हैं।

String[] map = new String[10]; 
String x = "foo"; 
String y = "bar"; 
String z = "baz"; 
map[0] = x; 
map[1] = y; 
map[2] = x; 
//... 
2

कुंजी/मूल्य जोड़ी को उलटा क्यों नहीं? मूल्यों के लिए एक सेट या सरणी का उपयोग करें:

x->{3, 4} 
y->{0, 1, 2, 5, 7} 
z->{6, 8, 9} 
-1

जावा हो जाता है ताकि आप स्मृति को बचाने के लिए मैन्युअल रूप से यह करने के लिए की जरूरत नहीं है, आप के लिए स्ट्रिंग संदर्भ को मजबूत करेगा। आप केवल हैश मैप में चाबियाँ/मान डाल सकते हैं।

+1

यह सच नहीं है। यदि यह एक शाब्दिक है, तो संकलक स्ट्रिंग्स को इंटर्न करेगा ताकि बराबर अक्षर को उसी स्ट्रिंग ऑब्जेक्ट द्वारा प्रतिस्थापित किया जा सके, और आप मैन्युअल रूप से 'intern()' को कॉल कर सकते हैं, लेकिन जावा कभी भी रनटाइम पर कभी भी इसे स्वचालित रूप से/स्वचालित रूप से नहीं करेगा।एक बार जब आप स्ट्रिंग जावा का संदर्भ लेते हैं तो दृश्यों के पीछे किसी अन्य को इंगित करने के लिए उस संदर्भ को नहीं बदलेगा, और आप हमेशा 'नए' कीवर्ड का उपयोग करके उसी स्ट्रिंग के अनूठे उदाहरण प्राप्त कर सकते हैं। तो उदाहरण के लिए इनपुट इनपुट या उपयोगकर्ता इनपुट से स्ट्रिंग्स के लिए ऐसा कोई भी नहीं होता है। –

1

यदि आपको पीट किर्कहम के सुझाव (जो सबसे अच्छा तरीका होगा, आईएमओ) पसंद नहीं है, तो आप Google संग्रह (एर ... Guava अब) MultiMap का उपयोग कर सकते हैं।

+4

मैं मल्टीमैप को भी सुझाव देने जा रहा था लेकिन वह विपरीत के बजाए एक ही मूल्य पर मैपिंग के लिए कई कुंजी मैपिंग की तलाश में है। – Stevko

0

प्रत्येक नक्शे प्रविष्टि एक मूल्य है कि सैद्धांतिक रूप से 2.

में रखा जा सकता कुंजी 1 हर कई सौ पूर्णांकों के आदेश पर कुछ संख्या से अधिक घने हैं प्रतिनिधित्व करने के लिए कई सौ टुकड़े का उपयोग करेगा, यह हो जाएगा मानचित्र का उपयोग न करने के लिए तेज़ और छोटा, लेकिन एक सरणी - Trove TByteArrayList जैसी कुछ - जहां बाइट मान आपके तारों पर मैप किए जाते हैं। यदि आप 4x अधिक घनत्व प्राप्त करना चाहते हैं, तो 4 मानों को एक बाइट में पैक करें।

यह बहुत ही समझ में आता है जब आपके पास बहुत अधिक डेटा है - लेकिन आपने लाखों चाबियाँ कहा, इसलिए मुझे लगता है कि यह एक अच्छा फिट है।

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