2012-05-06 71 views
6

我剛剛移植我所有的數組的ArrayList(因爲我非常缺乏的Java知識,我不知道基本的數組類型沒有任何「新增」選項)在我的小程序,一切似乎罰款...除了不時拋出一個異常,但自相矛盾:另一個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) 

的代碼的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

是否有你不使用[for-each loop](http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html)的理由? – amit

回答

11

這將是一個併發修改問題。這是你得到這個錯誤的唯一方法。

您沒有收到併發修改錯誤的原因是因爲你是通過做循環的方式不會創建一個迭代器,因此沒有機會提供了一種用於併發修改錯誤被拋出。

我會建議同步您的arraylist 或使用諸如 CopyOnWriteArrayList 之類的東西。

編輯:對不起寫入時複製不會爲這個具體問題的工作。你需要切換到一個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)); 
    } 
} 

,這將很可能導致concurrentmodification錯誤被拋出。在這一點上,您可以將您的ArrayList切換到CopyOnWriteArrayList或同步它。

+2

它會在沒有每個循環的情況下工作嗎?正如我從javadoc瞭解到的,CopyOnWriteArrayList有助於創建新的迭代器(我們用於每個循環)。這是對的嗎? –

+1

@NikitaBeloglazov你是對的。他需要切換到每個循環,然後他可以在寫入時使用副本,以避免他將得到的併發修改問題。我編輯了我的答案以反映這一點。 – Krrose27

+0

Wowowow,這超過了我的業餘Java級別,學習時間;) – LosTChG

相關問題