1. इटरेटर कैसे बने इसकी पृष्ठभूमि
आप पहले से ही परिचित हैं HashSet
। यदि आपने वास्तव में इसकी जांच की है, सिर्फ एक पाठ पढ़ने से परे, तो आपको यह प्रश्न पूछना चाहिए था:
मैं स्क्रीन पर सभी हैशसेट तत्वों की सूची कैसे प्रदर्शित करूं? आखिरकार, इंटरफ़ेस में get()
और set()
तरीके नहीं हैं!
और HashSet
इस सीमा में अकेला नहीं है। इसके अलावा HashSet
, कई अन्य संग्रह हैं जो तत्वों को अनुक्रमणिका द्वारा पुनर्प्राप्त करने की अनुमति नहीं देते हैं, क्योंकि तत्वों का कोई परिभाषित क्रम नहीं है।
पिछले कुछ वर्षों में, प्रोग्रामर ने कई जटिल डेटा संरचनाओं का आविष्कार किया है, जैसे ग्राफ और पेड़। या सूचियों की सूची।
जब नए तत्व जोड़े जाते हैं या मौजूदा तत्वों को हटा दिया जाता है, तो कई कंटेनर अपने तत्वों का क्रम बदल देते हैं। उदाहरण के लिए, एक सूची तत्वों को एक विशेष क्रम में संग्रहीत करती है, और जब कोई नया तत्व जोड़ा जाता है, तो यह लगभग हमेशा सूची के बीच में डाला जाता है।
और हमें ऐसी परिस्थितियाँ भी मिलती हैं जहाँ एक कंटेनर होता है जो तत्वों को संग्रहीत करता है लेकिन किसी निश्चित क्रम में नहीं।
अब मान लीजिए कि हम ऐसे संग्रह से सभी तत्वों को एक सरणी या सूची में कॉपी करना चाहते हैं। हमें सभी तत्वों को प्राप्त करने की आवश्यकता है। हम उस क्रम के बारे में परवाह नहीं करते हैं जिसमें हम तत्वों पर पुनरावृति करते हैं - महत्वपूर्ण बात यह है कि समान तत्वों पर एक से अधिक बार पुनरावृति न करें। हम इसे कैसे करते हैं?
2. संग्रह के लिए इटरेटर
उपरोक्त समस्या के समाधान के रूप में इटरेटर प्रस्तावित किए गए थे।
एक पुनरावर्तक एक संग्रह से जुड़ी एक विशेष वस्तु है, जो बिना किसी को दोहराए संग्रह के सभी तत्वों को पार करने में मदद करता है।
आप किसी संग्रह के लिए पुनरावर्तक प्राप्त करने के लिए निम्न कोड का उपयोग कर सकते हैं:
Iterator<Type> it = name.iterator();
जहां name
संग्रह चर का नाम है, Type
संग्रह के तत्वों का प्रकार है, iterator()
संग्रह के तरीकों में से एक है, और it
पुनरावर्तक चर का नाम है।
एक पुनरावर्तक वस्तु में 3 विधियाँ होती हैं:
तरीका | विवरण |
---|---|
|
संग्रह में अगला तत्व लौटाता है |
|
जाँचता है कि क्या कोई तत्व है जो अभी तक ट्रैवर्स नहीं किया गया है |
|
संग्रह के वर्तमान तत्व को हटाता है |
ये विधियाँ कुछ हद तक स्कैनर वर्ग nextInt)
और hasNextInt()
विधियों के समान हैं।
विधि next()
उस संग्रह का अगला तत्व लौटाती है जिससे हमें पुनरावृत्त मिला।
विधि hasNext()
जाँचती है कि क्या संग्रह में अतिरिक्त तत्व हैं जो कि पुनरावर्तक अभी तक वापस नहीं आया है।
यहां ए के सभी तत्वों को प्रदर्शित करने का तरीका बताया गया है HashSet
:
कोड | टिप्पणियाँ |
---|---|
|
HashSet एक वस्तु बनाएँ जो String तत्वों को संग्रहीत करती है। हम चर में विभिन्न भाषाओं में अभिवादन जोड़ते हैं । सेट के लिए एक पुनरावर्तक वस्तु प्राप्त करें । जब तक तत्व हैं अगला तत्व प्राप्त करें स्क्रीन पर तत्व प्रदर्शित करें set set |
3. For-each
पाश
पुनरावर्तक का मुख्य नुकसान यह है कि for
लूप का उपयोग करने से आपका कोड अधिक बोझिल हो जाता है।
for
तुलना करने के लिए, एक लूप का उपयोग करके और एक पुनरावर्तक का उपयोग करके एक सूची प्रदर्शित करें :
इटरेटर | पाश के लिए |
---|---|
|
|
ArrayList
हां, लूप का उपयोग करके तत्वों को पार करना बहुत बेहतर है - सब कुछ छोटा हो जाता है।
लेकिन जावा के रचनाकारों ने फिर से हम पर कुछ चीनी डालने का फैसला किया। सौभाग्य से हमारे लिए, यह सिंटैक्टिक चीनी थी ।
उन्होंने जावा को एक नए प्रकार का लूप दिया और उसे for-each
लूप कहा। यह सामान्य रूप में कैसा दिखता है:
for(Type name:collection)
collection
संग्रह चर का नाम कहाँ है, Type
संग्रह में तत्वों का प्रकार है, और name
एक चर का नाम है जो लूप के प्रत्येक पुनरावृत्ति पर संग्रह से अगला मान लेता है।
इस प्रकार का लूप एक निहित पुनरावर्तक का उपयोग करके संग्रह के सभी तत्वों के माध्यम से पुनरावृत्त करता है। यह वास्तव में कैसे काम करता है:
प्रत्येक पाश के लिए | संकलक क्या देखता है: एक पुनरावर्तक के साथ लूप |
---|---|
|
|
जब कंपाइलर for-each
आपके कोड में एक लूप का सामना करता है, तो यह बस इसे दाईं ओर के कोड से बदल देता है: यह किसी अन्य लापता विधि कॉल के साथ एक पुनरावर्तक प्राप्त करने के लिए कॉल जोड़ता है।
प्रोग्रामर for-each
लूप को पसंद करते हैं और लगभग हमेशा इसका उपयोग तब करते हैं जब उन्हें किसी संग्रह के सभी तत्वों पर पुनरावृति करने की आवश्यकता होती है।
ArrayList
लूप का उपयोग करके किसी सूची पर पुनरावृति करना भी for-each
छोटा दिखता है:
प्रत्येक पाश के लिए | पाश के लिए |
---|---|
|
|
4. एक for-each
पाश में एक तत्व को हटाना
लूप for-each
में एक खामी है: यह तत्वों को सही ढंग से नहीं निकाल सकता है। यदि आप इस तरह का कोड लिखते हैं, तो आपको एक त्रुटि मिलेगी।
कोड | टिप्पणी |
---|---|
|
हटाने की कार्रवाई एक त्रुटि उत्पन्न करेगी! |
यह एक बहुत अच्छा और समझने योग्य कोड है, लेकिन यह काम नहीं करेगा।
जब आप इसे पुनरावर्तक के साथ घुमा रहे हों तो आप संग्रह को बदल नहीं सकते हैं।
इस सीमा के आसपास जाने के तीन तरीके हैं।
1. एक अलग तरह के लूप का इस्तेमाल करें
When traversing an ArrayList collection
i
, आप एक काउंटर चर के साथ एक साधारण पाश का उपयोग कर सकते हैं ।
कोड |
---|
|
HashSet
हालांकि, यह विकल्प और HashMap
संग्रह के लिए उपयुक्त नहीं है
2. एक स्पष्ट पुनरावर्तक का प्रयोग करें
आप एक पुनरावर्तक का स्पष्ट रूप से उपयोग कर सकते हैं और इसकी remove()
विधि को कॉल कर सकते हैं।
संस्करण जो काम करता है | संस्करण जो काम नहीं करता |
---|---|
|
|
ध्यान दें कि हम remove()
इटेटरेटर ऑब्जेक्ट पर विधि कहते हैं! इटरेटर जानता है कि आइटम हटा दिया गया है और स्थिति को सही ढंग से संभाल सकता है।
3. संग्रह की एक प्रति का उपयोग करें
आप संग्रह की प्रतिलिपि भी बना सकते हैं और फिर प्रतिलिपि का उपयोग for-each
लूप में कर सकते हैं और मूल संग्रह से तत्वों को हटा सकते हैं।
कोड | टिप्पणी |
---|---|
|
संग्रह की प्रतिलिपि बनाना बेहद आसान है लूप संग्रह की प्रति के लिए पुनरावर्तक का उपयोग करता है। संग्रह से तत्वों को हटा दिया जाता है । list |
संग्रह को जल्दी से कॉपी किया जाता है, क्योंकि तत्व स्वयं डुप्लिकेट नहीं होते हैं। इसके बजाय, नया संग्रह उन तत्वों के संदर्भों को संग्रहीत करता है जो पुराने संग्रह में पहले से मौजूद हैं।
GO TO FULL VERSION