2012-05-06 2 views
6

Я только что портировал все мои массивы в ArrayList (из-за моей большой нехватки знаний в Java я не знал, что базовый тип массива не имеет никакого «.add» опция) в моей маленькой программе и все, кажется, хорошо ... кроме того, что время от времени возникает исключение, но это противоречит сам себе:Другое java.lang.IndexOutOfBoundsException, но index <размер

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) 

блок кода, Java указать мне на это:

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

есть ли конкретная причина, почему ваша петля начинается с @ 1, а не 0? –

+2

Есть ли причина, по которой вы не используете [для каждого цикла] (http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html)? – amit

ответ

11

Это будет проблема одновременной модификации. Это единственный способ получить эту ошибку.

Причина, по которой вы не получаете ошибку одновременной модификации, заключается в том, что способ, которым вы выполняете цикл, не создает итератор, и поэтому нет возможности для одновременной модификации ошибки.

Я бы предложил синхронизацию на вашем arraylist или используя что-то вроде CopyOnWriteArrayList .

Редактировать: Sorry CopyOnWrite не будет работать для этой конкретной проблемы. Для этого вам нужно переключиться на цикл foreach.

В ответ на ваш комментарий ниже:

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

, а затем добавить подобную 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

@ НикитаБелоглазов вы правы. Ему нужно переключиться на a для каждого цикла, а затем он может использовать копию для записи, чтобы избежать проблемы с одновременной модификацией, которую он получит. Я отредактировал свой ответ, чтобы отразить это. – Krrose27

+0

Wowowow, это превосходит мой любительский уровень java, время учебы;) – LosTChG

Смежные вопросы