2012-05-06 6 views
6

Ho appena portato tutti i miei array a ArrayList (a causa della mia grande mancanza di conoscenza in Java non sapevo che il tipo di array di base non ha alcun ".add" opzione) nel mio piccolo programma e tutto sembra bene ... tranne che di volta in volta viene generata un'eccezione, ma si contraddice:Un'altra java.lang.IndexOutOfBoundsException, ma indice <dimensioni

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) 

Il blocco di codice che Java punto me è questo:

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)); 
    } 
} 

L'errore non sta causando alcun problema alle prestazioni del programma. Tuttavia, apprezzerei che qualcuno potesse spiegarmi qual è la causa di questa eccezione.

Grazie!

+1

potresti voler avviare il ciclo a 0 a meno che non sia un valore speciale ... –

+0

c'è un motivo specifico per cui il tuo ciclo inizia @ 1 anziché 0? –

+2

C'è un motivo per cui non si usa [for-each loop] (http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html)? – amit

risposta

11

Questo sarà un problema di modifica simultanea. È l'unico modo per ottenere questo errore.

Il motivo per cui non si verifica un errore di modifica simultanea è perché il modo in cui si sta eseguendo il ciclo non crea un iteratore e pertanto non viene fornita alcuna possibilità di generare un errore di modifica simultanea.

Vorrei suggerire la sincronizzazione sul tuo arrayist o utilizzare qualcosa come CopyOnWriteArrayList .

Modifica: Spiacente CopyOnWrite non funzionerà per questo problema specifico. È necessario passare a un ciclo foreach perché sia ​​un'opzione.

In risposta al tuo commento qui sotto:

Sincronizzazione:

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)); 
    } 
} 

e quindi aggiungere un simile synchronized(elipsasCol){} intorno altrove si tocca elipsasCol.

o

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)); 
    } 
} 

che molto probabilmente causare un errore concurrentmodification per essere gettato. A quel punto è possibile passare ArrayList a CopyOnWriteArrayList o sincronizzarsi attorno ad esso.

+2

Funzionerà senza per ogni ciclo? Come capisco da javadoc 'CopyOnWriteArrayList' aiuta quando viene creato un nuovo iteratore (che usiamo per ogni ciclo). È corretto? –

+1

@NikitaBeloglazov sei corretto. Deve passare a un ciclo per ogni ciclo e quindi può utilizzare una copia su scrittura per evitare il problema di modifica simultanea che otterrà. Ho modificato la mia risposta per riflettere questo. – Krrose27

+0

Wowowow, questo supera il mio livello java amatoriale, è ora di studiare;) – LosTChG

Problemi correlati