2011-11-18 4 views
5

से तत्वों को गतिशील रूप से हटा रहा है मुझे सूची के माध्यम से एक सूची के तत्वों को हटाने में कोई समस्या है। कोड:सूची

For (WebElement element: list){ 
    if (!element.isEnabled() || !element.isSelected()){ 
     list.remove(element); 
    } 
} 

मैं एक ConcurrentModificationException है, जो मैं पूरी तरह समझ में मिलता है। सूची में जाने वाले लूप में मैं एक सूची से किसी आइटम को हटा रहा हूं। सहजता से, यह लूप के अनुक्रमण को खराब कर देगा।

मेरा सवाल है, मैं इस सूची से enabled या selected या तो उन तत्वों को कैसे हटा सकता हूं?

उत्तर

8

एक पाश में एक सूची से तत्वों को दूर करने के लिए सबसे आसान तरीका दिनचर्या iterator.remove()

+0

मुझे नहीं पता कि यह जरूरी है कि यह सबसे आसान है या नहीं। 'Iterator 'इंटरफ़ेस पर' निकालें()' कार्यक्षमता का एक वैकल्पिक टुकड़ा है। यह ध्यान देने योग्य भी है कि 'हटाएं() '' Iterator ' पर है, और केवल 'ListIterator ' द्वारा विरासत में मिला है। – corsiKa

6

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

Iterator<WebElement> iter = list.iterator(); 
while (iter.hasNext()) { 
    WebElement element = iter.next(); 
    if (!element.isEnabled() || !element.isSelected()) { 
     iter.remove(); 
    } 
} 

अधिक के लिए this question देखें।

+0

हम्म मैं देखता हूं। इसलिए यदि मैं 'Iterator' को वापस 'सूची' में परिवर्तित करना चाहता हूं, तो क्या प्रत्येक तत्व को एक लूप में एक-एक करके जोड़ने का एक आसान तरीका है? – jamesfzhang

+2

यह 'सूची' को' इटरेटर 'में परिवर्तित नहीं करता है - एक' इटरेटर 'केवल एक ऑब्जेक्ट है जो उस सूची पर ही कार्य करता है - यह सूची के माध्यम से पुन: प्रयास करने के लिए एक इंटरफ़ेस है। जब आप 'iter.remove()' को कॉल करते हैं, तो यह वास्तव में अंतर्निहित सूची को संशोधित कर रहा है। – Claudiu

+0

वाह, यह आश्चर्यजनक है! धन्यवाद। – jamesfzhang

0

ConcurrentModificationException इस तथ्य से परिणाम यह है कि प्रत्येक वाक्यविन्यास इटरेटर इंटरफ़ेस का उपयोग करने के लिए सिंटैक्टिक चीनी है।

सूची इटरेटर्स को "असफल-तेज" विशेषता के रूप में जाना जाता है, जिसका अर्थ यह है कि इटरेटर द्वारा प्रदान किए गए इंटरफ़ेस से अलग सूची में किए गए किसी भी बदलाव को तुरंत इटरेटर कहा जाता है। एक अमान्य इटरेटर का उपयोग करने का प्रयास आपके अपवाद को ट्रिगर करता है।

@ क्लाउडियो पहले से ही इस कोड को पोस्ट कर चुका है, लेकिन स्पष्टता के लिए, मैं इसे यहां भी रखूंगा। ऐसा करने के लिए जो आप करने की कोशिश कर रहे हैं, आपको फैंसी सिंटैक्स छोड़ना होगा और एक नंगे इटरेटर का उपयोग करना होगा।

Iterator<WebElement iter = list.iterator(); 
while (iter.hasNext()) { 
    WebElement element = iter.next(); 
    if (!element.isEnabled() || !element.isSelected()) { 
     iter.remove(); 
    } 
} 
3

अन्य ने सूची इटरेटर का उपयोग करने का सुझाव दिया है। यह मेरे लिए उपयोगी साबित हुआ है, लेकिन दुर्भाग्यवश यह एक विधि, remove() पर निर्भर करता है, जिसे Iterable<E> इंटरफ़ेस द्वारा वैकल्पिक माना जाता है।

शून्य निकालें()

अंतर्निहित संग्रह पिछले तत्व इटरेटर (वैकल्पिक आपरेशन) द्वारा लौटाए से निकालता है:

जावाडोक, फिर कभी नहीं (जोर मेरा) Quoth

मेरे आसपास और अधिक उपयोगी साबित होने के लिए एक हटाने की सूची है।

List<E> removed = new ArrayList<E>(); 
for(E element : list) { 
    if(someCondition) removed.add(element); 
} 
list.removeAll(removed); 

इसमें आपके द्वारा हटाए गए कार्यों का इतिहास देने का अतिरिक्त लाभ है, जैसे कि निकाली विधि करता है।

+0

मुझे यह बहुत पसंद है (+1)। हालांकि, तत्व ई के बराबर बराबर विधि – GETah

+1

@GETah के उचित ओवरराइड होना चाहिए। यह इसके बिना ठीक काम करेगा, और इसे भी पसंद किया जा सकता है। आप उन्हें फैक्ट्री विधि से आ सकते हैं, जिसमें समानता के संदर्भ में सख्ती से भरोसा करते हुए, बराबर विधि के लिए आपके पास बहुत कम आवश्यकता है। – corsiKa

+1

वाह मुझे यह बहुत पसंद है! बॉक्स सोच के बाहर बहुत अच्छा है। – jamesfzhang