2012-05-06 12 views
6

Tüm dizilerimi ArrayList'e taşıdım (Java'daki bilgi eksikliğim nedeniyle temel Array türünde herhangi bir ".add" olduğunu bilmiyordum) o zaman zaman bir özel durum hariç benim küçük program ve her şeyde opsiyon) ... iyi görünüyor, ancak kendisi ile çelişen:Başka bir java.lang.IndexOutOfBoundsException, ancak dizin <boyutu

:

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 beni işaret kod bloğu şudur için

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

Hata, programın performansında sorun yaratmıyor. Bununla birlikte, birisinin bana bu istisnanın sebebinin ne olduğunu açıklayabileceğini takdir ediyorum.

Teşekkür ederiz!

+1

Özel bir değer olmadıkça, döngü 0'a başlamak isteyebilirsiniz ... –

+0

, döngüsünüzün neden 0 yerine 0 yerine başladığına dair belirli bir neden var mı? –

+2

Her bir döngü için kullanmamanın bir nedeni var mı (http://docs.oracle.com/javase/1.5.0/docs/guide/language/foreach.html)? – amit

cevap

11

Bu eşzamanlı bir değişiklik sorunu olacak. Bu hatayı alabilmenin tek yolu budur.

Eşzamanlı bir değişiklik hatası almamanızın nedeni, döngüyü yaptığınız yolun bir yineleyici oluşturmaması ve eşzamanlı bir değişiklik hatasının atılması için hiçbir şans tanınmamasıdır.

Arraylist üzerinde eşitleme yapmanızı veya CopyOnWriteArrayList gibi bir şey kullanmanızı öneririm.

Düzenleme: Üzgünüm CopyOnWrite bu belirli sorun için çalışmaz. Bir seçenek olması için bir foreach döngüsüne geçmeniz gerekiyor. Aşağıdaki Yorum yanıt

:

Senkronizasyon:

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

ve sonra başka bir yerde elipsasCol dokunmak etrafında benzer synchronized(elipsasCol){} ekleyin. büyük olasılıkla bir concurrentmodification hataya neden olur

veya

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

atılmasına. Hangi noktada ArrayList'inizi bir CopyOnWriteArrayList'e geçirebilir veya etrafında senkronize edebilirsiniz.

+2

Her döngü için çalışmaz mı? Javadoc 'CopyOnWriteArrayList'den anladığım gibi, yeni yineleyici oluşturulduğunda yardımcı oluyor (her döngü için kullanıyoruz). Doğru mu? –

+1

@NikitaBeloglazov siz doğru. Her bir döngü için bir geçiş yapması gerekiyor ve o zaman alacağı eşzamanlı modifikasyon sorunundan kaçınmak için bir kopyasını yazabilir. Bunu yanıtlamak için cevabımı düzenledim. – Krrose27

+0

Wowowow, bu benim amatörce java seviyemi aştı, çalışma zamanı;) – LosTChG

İlgili konular