Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Another java.lang.IndexOutOfBoundsException, but index < size

I've just ported all my arrays to ArrayList (due to my great lack of knowledge in Java I didn't know basic Array type does not have any ".add" option) in my little program and everything seems fine... except that from time to time an exception is thrown, but it contradicts itself:

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)

The block of code that Java point me to is this:

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

The error isn't causing any trouble to the performance of the program. However, I would appreciate that someone can explain me what is the cause of this exception.

Thank you!

like image 573
LosTChG Avatar asked May 06 '12 21:05

LosTChG


1 Answers

This is going to be a concurrent modification issue. It is the only way you can get that error.

The reason you do not receive a concurrent modification error is because the way you are doing the looping through doesn't create an iterator and as such no chance is provided for a concurrent modification error to be thrown.

I would suggest syncing on your arraylist or using something such as a CopyOnWriteArrayList.

Edit: Sorry CopyOnWrite will not work for this specific issue. You need to switch to a foreach loop for it to be an option.

In response to your comment below:

Synchronizing:

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

and then add a similar synchronized(elipsasCol){} around anywhere else you touch elipsasCol.

or

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

which will most likely cause a concurrentmodification error to be thrown. At which point you can switch your ArrayList to a CopyOnWriteArrayList or synchronize around it.

like image 91
Krrose27 Avatar answered Nov 17 '22 03:11

Krrose27