कुछ से बचने के लिए कुछ विकल्पों के साथ कुछ उदाहरण देता हूं ConcurrentModificationException
।
मान लीजिए हमारे पास पुस्तकों का निम्नलिखित संग्रह है
List<Book> books = new ArrayList<Book>();
books.add(new Book(new ISBN("0-201-63361-2")));
books.add(new Book(new ISBN("0-201-63361-3")));
books.add(new Book(new ISBN("0-201-63361-4")));
लीजिए और निकालें
पहली तकनीक में उन सभी वस्तुओं को इकट्ठा करना शामिल है जिन्हें हम हटाना चाहते हैं (जैसे कि लूप के लिए बढ़ाया का उपयोग करके) और पुनरावृति समाप्त करने के बाद, हम सभी मिली हुई वस्तुओं को हटा देते हैं।
ISBN isbn = new ISBN("0-201-63361-2");
List<Book> found = new ArrayList<Book>();
for(Book book : books){
if(book.getIsbn().equals(isbn)){
found.add(book);
}
}
books.removeAll(found);
यह मानकर चल रहा है कि आप जो ऑपरेशन करना चाहते हैं वह "डिलीट" है।
यदि आप "जोड़ना" चाहते हैं, तो यह दृष्टिकोण भी काम करेगा, लेकिन मैं आपको एक अलग संग्रह पर यह निर्धारित करने के लिए बताऊंगा कि आप किन तत्वों को दूसरे संग्रह में जोड़ना चाहते हैं और फिर addAll
अंत में एक विधि जारी करें ।
ListIterator का उपयोग करना
यदि आप सूचियों के साथ काम कर रहे हैं, तो एक और तकनीक का उपयोग किया जाता है ListIterator
जिसमें पुनरावृत्ति के दौरान वस्तुओं को हटाने और जोड़ने के लिए समर्थन होता है।
ListIterator<Book> iter = books.listIterator();
while(iter.hasNext()){
if(iter.next().getIsbn().equals(isbn)){
iter.remove();
}
}
फिर, मैंने ऊपर दिए गए उदाहरण में "हटाएं" विधि का उपयोग किया, जो कि आपके प्रश्न को स्पष्ट रूप से प्रतीत होता है, लेकिन आप add
पुनरावृत्ति के दौरान नए तत्वों को जोड़ने के लिए इसकी विधि का उपयोग भी कर सकते हैं ।
JDK> = 8 का उपयोग करना
जावा 8 या बेहतर संस्करणों के साथ काम करने वालों के लिए, कुछ अन्य तकनीकें हैं जिनका आप इसका लाभ उठा सकते हैं।
आप बेस क्लास removeIf
में नई विधि का उपयोग कर सकते हैं Collection
:
ISBN other = new ISBN("0-201-63361-2");
books.removeIf(b -> b.getIsbn().equals(other));
या नई स्ट्रीम API का उपयोग करें:
ISBN other = new ISBN("0-201-63361-2");
List<Book> filtered = books.stream()
.filter(b -> b.getIsbn().equals(other))
.collect(Collectors.toList());
इस अंतिम स्थिति में, किसी संग्रह से तत्वों को फ़िल्टर करने के लिए, आप फ़िल्टर किए गए संग्रह (यानी books = filtered
) के मूल संदर्भ को पुन: असाइन करते हैं या फ़िल्टर किए गए संग्रह को removeAll
मूल संग्रह (यानी books.removeAll(filtered)
) से मिले तत्वों में उपयोग करते हैं ।
सबलिस्ट या सबसेट का उपयोग करें
अन्य विकल्प भी हैं। यदि सूची को क्रमबद्ध किया गया है, और आप लगातार तत्वों को हटाना चाहते हैं, तो आप एक सबलिस्ट बना सकते हैं और फिर इसे साफ कर सकते हैं:
books.subList(0,5).clear();
चूँकि सबलिस्ट मूल सूची द्वारा समर्थित है, इसलिए यह तत्वों के इस सबकोलेक्शन को दूर करने का एक प्रभावी तरीका होगा।
NavigableSet.subSet
विधि का उपयोग करके सॉर्ट किए गए सेट के साथ कुछ समान हासिल किया जा सकता है , या वहां की पेशकश की गई किसी भी टुकड़ा करने की विधि।
बातें:
आप किस विधि का उपयोग करते हैं, इस पर निर्भर हो सकता है कि आप क्या करने का इरादा कर रहे हैं
- संग्रह और
removeAl
तकनीक किसी भी संग्रह (संग्रह, सूची, सेट, आदि) के साथ काम करती है।
ListIterator
तकनीक स्पष्ट रूप से केवल प्रदान की उनकी यह देखते हुए कि, सूचियों के साथ काम करता ListIterator
कार्यान्वयन प्रदान करता है जोड़ और निकाल संचालन के लिए समर्थन करते हैं।
Iterator
दृष्टिकोण संग्रह के किसी भी प्रकार के साथ काम करेंगे, लेकिन यह केवल निकालने के संचालन का समर्थन करता है।
- जब तक हम इसे हटाते हैं, तब तक
ListIterator
/ के साथ Iterator
स्पष्ट लाभ कुछ भी कॉपी करने के लिए नहीं है। तो, यह बहुत ही कुशल है।
- जेडीके 8 स्ट्रीम उदाहरण वास्तव में कुछ भी नहीं हटाते हैं, लेकिन वांछित तत्वों की तलाश करते हैं, और फिर हमने मूल संग्रह संदर्भ को नए के साथ बदल दिया, और पुराने को कचरा एकत्र करने दें। इसलिए, हम संग्रह पर केवल एक बार पुनरावृत्ति करते हैं और यह कुशल होगा।
- संग्रह में और
removeAll
नुकसान यह है कि हमें दो बार पुनरावृति करनी होगी। पहले हम फुर-लूप में एक ऐसी वस्तु की खोज करते हैं जो हमारे निष्कासन मानदंडों से मेल खाती है, और एक बार जब हम इसे पा लेते हैं, तो हम इसे मूल संग्रह से हटाने के लिए कहते हैं, जो इस आइटम को देखने के लिए दूसरा पुनरावृत्ति कार्य होगा। इसे हटा दो।
- मुझे लगता है कि यह ध्यान देने योग्य है कि
Iterator
इंटरफ़ेस की निष्कासन विधि को Javadocs में "वैकल्पिक" के रूप में चिह्नित किया गया है, जिसका अर्थ है कि ऐसे Iterator
कार्यान्वयन हो सकते हैं जो UnsupportedOperationException
हम हटाने की विधि को लागू करते हैं। जैसे, मैं कहूंगा कि यह दृष्टिकोण दूसरों की तुलना में कम सुरक्षित है अगर हम तत्वों को हटाने के लिए पुनरावृत्त समर्थन की गारंटी नहीं दे सकते हैं।