2012-05-06 7 views
6

मैंने अभी अपने सभी सरणी को ArrayList पर पोर्ट किया है (जावा में ज्ञान की मेरी बड़ी कमी के कारण मुझे नहीं पता था कि मूल ऐरे प्रकार में कोई ".add" नहीं है विकल्प) मेरी छोटी कार्यक्रम है और सब कुछ में ठीक सिवाय इसके कि समय-समय पर एक अपवाद फेंक दिया है लगता है ..., लेकिन यह अपने आप के विपरीत है:एक और java.lang.IndexOutOfBoundsException, लेकिन सूचकांक <आकार

:

Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Index: 17, Size: 21 
    at java.util.ArrayList.rangeCheck(ArrayList.java:604) 
    at java.util.ArrayList.get(ArrayList.java:382) 
    at guay.Puntitos.AumentarTamano(Puntitos.java:346) 
    at guay.Guay$MiMouse.mouseMoved(Guay.java:226) 
    at java.awt.Component.processMouseMotionEvent(Component.java:6550) 
    at java.awt.Component.processEvent(Component.java:6274) 
    at java.awt.Container.processEvent(Container.java:2229) 
    at java.awt.Window.processEvent(Window.java:2016) 
    at java.awt.Component.dispatchEventImpl(Component.java:4861) 
    at java.awt.Container.dispatchEventImpl(Container.java:2287) 
    at java.awt.Window.dispatchEventImpl(Window.java:2713) 
    at java.awt.Component.dispatchEvent(Component.java:4687) 
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:707) 
    at java.awt.EventQueue.access$000(EventQueue.java:101) 
    at java.awt.EventQueue$3.run(EventQueue.java:666) 
    at java.awt.EventQueue$3.run(EventQueue.java:664) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87) 
    at java.awt.EventQueue$4.run(EventQueue.java:680) 
    at java.awt.EventQueue$4.run(EventQueue.java:678) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76) 
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:677) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:211) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113) 
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105) 
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90) 

कोड के ब्लॉक है कि जावा मुझे बात यह है करने के लिए

for (int i = 1; i < elipsasCol.size(); i++) { 
    if (elipsasCol.get(i) != null && elipsasCol.get(i).contains(mouse)) { 
    // This line      
    double modulo = Math.sqrt(Math.pow(mouse.x - elipsasCol.get(i).getCenterX(), 2) 
          + Math.pow(mouse.y - elipsasCol.get(i).getCenterY(), 2)); 
    } 
} 

त्रुटि प्रोग्राम के प्रदर्शन में कोई परेशानी नहीं पैदा कर रही है। हालांकि, मैं सराहना करता हूं कि कोई मुझे बता सकता है कि इस अपवाद का कारण क्या है।

धन्यवाद!

+1

आप लूप को 0 पर शुरू करना चाहते हैं जब तक कि यह एक विशेष मूल्य न हो ... –

+0

क्या आपका लूप 0 के बजाय @ 1 क्यों शुरू होता है? –

+2

क्या कोई कारण है कि आप [प्रत्येक-लूप के लिए] का उपयोग नहीं करते हैं (http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html)? – amit

उत्तर

11

यह एक समवर्ती संशोधन समस्या होने जा रहा है। यह एकमात्र तरीका है जिससे आप उस त्रुटि को प्राप्त कर सकते हैं।

कारण आपको समवर्ती संशोधन त्रुटि प्राप्त नहीं होती है क्योंकि जिस तरह से आप लूपिंग कर रहे हैं, वह एक इटरेटर नहीं बनाता है और इस तरह के एक समवर्ती संशोधन त्रुटि को फेंकने के लिए कोई मौका नहीं दिया जाता है।

मैं आपकी सरणीसूची पर सिंक्रनाइज़ करने का सुझाव दूंगा या CopyOnWriteArrayList जैसे कुछ का उपयोग करूँगा।

संपादित करें: क्षमा करें CopyOnWrite इस विशिष्ट समस्या के लिए काम नहीं करेगा। एक विकल्प होने के लिए आपको फ़ोरैच लूप पर स्विच करने की आवश्यकता है।

नीचे अपनी टिप्पणी के जवाब में:

सिंक्रनाइज़ करना:

synchronized(elipsasCol){ 
for (int i = 1; i < elipsasCol.size(); i++) { 
    if (elipsasCol.get(i) != null && elipsasCol.get(i).contains(mouse)) { 
    // This line      
    double modulo = Math.sqrt(Math.pow(mouse.x - elipsasCol.get(i).getCenterX(), 2) 
          + Math.pow(mouse.y - elipsasCol.get(i).getCenterY(), 2)); 
    } 
} 

और फिर एक समान synchronized(elipsasCol){} के आसपास कहीं और आप को छूने elipsasCol जोड़ें।

या

for (T obj : elipsasCol) { 
    if (obj != null && obj.contains(mouse)) { 
    // This line      
    double modulo = Math.sqrt(Math.pow(mouse.x - obj.getCenterX(), 2) 
          + Math.pow(mouse.y - obj.getCenterY(), 2)); 
    } 
} 

जो सबसे अधिक संभावना एक concurrentmodification त्रुटि का कारण होगा फेंक दिया है। उस बिंदु पर आप अपने ArrayList को CopyOnWriteArrayList पर स्विच कर सकते हैं या इसके चारों ओर सिंक्रनाइज़ कर सकते हैं।

+2

क्या यह प्रत्येक लूप के बिना काम करेगा? जैसा कि मैं javadoc 'CopyOnWriteArrayList' से समझता हूं जब नया इटरेटर बनाया जाता है (हम प्रत्येक लूप के लिए उपयोग करते हैं)। क्या यह सही है? –

+1

@ निकिताबेलोग्लाज़ोव आप सही हैं। उसे प्रत्येक लूप के लिए स्विच करने की आवश्यकता है और फिर वह समेकित संशोधन मुद्दे से बचने के लिए लिखने पर एक प्रतिलिपि का उपयोग कर सकता है। मैंने इसे प्रतिबिंबित करने के लिए अपना जवाब संपादित कर लिया है। – Krrose27

+0

वाहो, यह मेरे शौकिया जावा स्तर को पार करने के लिए, अध्ययन करने का समय;) – LosTChG

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

  • कोई संबंधित समस्या नहीं^_^