6

小さなプログラムですべての配列を ArrayList に移植しました (Java に関する知識が非常に不足しているため、基本的な配列型に ".add" オプションがないことを知りませんでした)。時々例外がスローされますが、それ自体に矛盾があります。

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

このエラーは、プログラムのパフォーマンスに問題を引き起こしていません。ただし、誰かがこの例外の原因を説明していただければ幸いです。

ありがとうございました!

4

1 に答える 1

11

これは、同時変更の問題になります。それはあなたがそのエラーを得ることができる唯一の方法です。

同時変更エラーが発生しない理由は、ループスルーを実行している方法ではイテレーターが作成されないため、同時変更エラーがスローされる可能性がないためです。

配列リストで同期するか、 CopyOnWriteArrayListなどを使用することをお勧めします。

編集:申し訳ありませんが、CopyOnWriteはこの特定の問題では機能しません。オプションにするには、foreachループに切り替える必要があります。

以下のコメントに応えて:

同期:

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

これにより、同時変更エラーがスローされる可能性があります。その時点で、ArrayListをCopyOnWriteArrayListに切り替えるか、それを中心に同期することができます。

于 2012-05-06T22:22:00.010 に答える