removeAll und ConcurrentModificationException

Status
Nicht offen für weitere Antworten.
N

na-oma

Gast
Meine Aufgabe lautet:

Create a class, then make an initialized array of objects of your class. Fill a List from your array. Create a subset of your List by using subList( ), then remove this subset from your List by using removeAll( ).

nun: frisch ans Werk:


Code:
import java.util.*;

class MyClass { }

public class Ueb22 {
	public static void main(String[] args) {

		MyClass[] mca = {new MyClass(), new MyClass(), new MyClass()};
		List al = new ArrayList();
		for (int i = 0; i < mca.length; i++) {
			al.add(mca[i]);
		}
		System.out.println(al);
		//al.subList(0, 1).clear(); //statt subList und removeAll
		List sl = al.subList(0, 1);
		al.removeAll(sl);           // (*)
		System.out.println(al);
	}
}

in der Zeile mit (*) bekomme ich:
Exception in thread "main" java.util.ConcurrentModificationException

Inzwischen kann ich mir das erklären:
-die SubListe ist ja immernoch "backed" von der originalen.
-Wenn ich dann removeAll mache, wird mittels Iterator auf der originalen Liste iteriert, diese wird durch löschung verändert
-*bumm*

Der Einzeiler durch den alles funktioniert, ist oben auskommentiert. Coole Lösung, hab ich in der API gefunden.

Allerdings frage ich mich: wie kann man die Aufgabe lösen, so wie sie gestellt ist? Einer ne Idee?

-Die sublist irgendwie kopieren wäre natürlich möglich...allerdings is das doch doof :)
 

Mag1c

Top Contributor
Hi,

Lösung:

es steht ja nicht explizit da, welches removeAll(...) du benutzen sollst ;)

Und da dachte ich mir ... probier doch mal ... und siehe da, es funktioniert :applaus:

sl.removeAll(al);

Gruß
Mag1c
 
N

na-oma

Gast
Also lass mich noch mal rekapitulieren:
(wer Bock hat kanns ja mal lesen, hauptsache ich habs jetz verstanden :) )


geht nicht:
al.removeAll(sl);

kommt immer:
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.SubList.checkForComodification(Unknown Source)
at java.util.SubList.listIterator(Unknown Source)
at java.util.AbstractList.listIterator(Unknown Source)
at java.util.SubList.iterator(Unknown Source)
at java.util.AbstractCollection.contains(Unknown Source)
at java.util.AbstractCollection.removeAll(Unknown Source)
at c11.Ueb22.Ueb22.main(Ueb22.java:21)

removeAll (von AbstractCollection geerbt)
(code etwas vereinfacht, return weggelassen und so)
Code:
public boolean removeAll(Collection<?> c) {
	Iterator<?> e = iterator();
	while (e.hasNext()) {
		if (c.contains(e.next())) {
			e.remove();
		}
	}
}

aha jetz hab ichs:
al.removeAll(sl);

Jede Liste hat einen modCount. Dieser wird bei jeder strukturellen Veränderung der Liste (wo deren Länge sich ändert) um 1 erhöht.
Wenn man eine SubList erzeugt, wird der modCount der alten Liste (al) in expectedModCount gespeichert:
Code:
expectedModCount = l.modCount;
Dann remove ich direkt ein Element der al. (deren modCount wird erhöht)
Dann bilde ich einen Iterator auf der SubListe (in sl.contains aus al.removeAll).
Der stellt noch im Konstruktor durch Aufruf von checkForComodification() fest:
Code:
private void checkForComodification() {
	if (l.modCount != expectedModCount)
		throw new ConcurrentModificationException();
}
Aha: da hat einer die Liste modifiziert (l.modCount wird ja direkt von der al abgerufen und expectedModCount ist immernoch der gleiche wie vor dem remove) also wirft er eine Exception.

Soweit so gut: jetzt der andere Fall:
sl.removeAll(al);

Wenn man eine SubList erzeugt, wird wieder der modCount der alten Liste (al) in expectedModCount gespeichert.
Dann remove ich ein Element der sl.
Jetzt kommt der Knackpunk:
Natürlich wird das Element aus der Ursprungsliste (al) gelöscht.
Dann wird der expectedmodCount der subList wieder auf den modCount der Ursprungsliste (al) gesetzt:
Code:
public void remove() {
	i.remove(); //element über iterator aus Ursprungsliste löschen
	expectedModCount = l.modCount;
	size--;
	modCount++;
}

Dann bilde ich wieder einen Iterator, diesmal auf die Ursprungsliste (al).
Der aktuelle modCount der Liste wird gespeichert:
Code:
int expectedModCount = modCount;
Dieser macht bei .next() checkForComodification:
Code:
final void checkForComodification() {
	if (modCount != expectedModCount)
		throw new ConcurrentModificationException();
}
Allerdings ist hier natürlich modCount gleich expectedModCount, da wir ja noch nichts removed haben.
deshalb geht das.
Dann wird evtl. wieder was removed, aber das geht alles glatt.

Der äußere Iterator, der der auf der subListe arbeitet wird auch nicht gestört, da ja immer dessen expectedmodCount dem der Ursprungsliste angegleichen wird.

Innere Klassen sind schon cool!
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
G Probleme mit removeAll() Java Basics - Anfänger-Themen 3
I Problem mit jPanel.removeAll() Java Basics - Anfänger-Themen 43
M removeAll() und neues Hinzufügen Java Basics - Anfänger-Themen 2
M Problem mit removeAll() im JApplet Java Basics - Anfänger-Themen 13
C removeAll() - TextField Java Basics - Anfänger-Themen 3
B Exception in thread "AWT-EventQueue-0" java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
temi ConcurrentModificationException Java Basics - Anfänger-Themen 32
C ConcurrentModificationException Java Basics - Anfänger-Themen 3
K Collections ConcurrentModificationException Java Basics - Anfänger-Themen 3
F Collections ConcurrentModificationException in ArrayList, mehrere Threads Java Basics - Anfänger-Themen 7
S ConcurrentModificationException Java Basics - Anfänger-Themen 4
H ConcurrentModificationException in HashMap Java Basics - Anfänger-Themen 2
Appleleptiker Datentypen ConcurrentModificationException Java Basics - Anfänger-Themen 5
Luk10 ConcurrentModificationException Java Basics - Anfänger-Themen 35
Luk10 ConcurrentModificationException Java Basics - Anfänger-Themen 15
H ConcurrentModificationException Java Basics - Anfänger-Themen 11
K java.util.ConcurrentModificationException problem in der Logik? Quaxli-Tutorial Java Basics - Anfänger-Themen 9
T ConcurrentModificationException bei HashMap Operation Java Basics - Anfänger-Themen 2
E java.util.ConcurrentModificationException Problem Java Basics - Anfänger-Themen 5
F java.util.ConcurrentModificationException Java Basics - Anfänger-Themen 8
S ArrayList ConcurrentModificationException Java Basics - Anfänger-Themen 4
J ConcurrentModificationException finden Java Basics - Anfänger-Themen 2
cowabunga1984 Objek löschen -> ConcurrentModificationException Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben