Iterator

0

Czy mógłby ktoś mi wytłumaczyć dlaczego program w drugiej wersji zwraca wyjątek? Miejsce zmienia tylko linijka z kodem: Iterator<Gerbil> it = gerbils.iterator();

import java.util.*;

import java.util.*;

class Gerbil {
private int gerbilNumber;
public Gerbil(int i) {
gerbilNumber = i;
}
public void hop() {
System.out.println("Gerbil " + gerbilNumber + " hops");
}
}

public class Test {
public static void main(String[] args) {
ArrayList<Gerbil> gerbils = new ArrayList<Gerbil>();
for(int i = 0; i < 10; i++)
gerbils.add(new Gerbil(i));
Iterator<Gerbil> it = gerbils.iterator(); // Chodzi o tą linijkę
while (it.hasNext()) {
Gerbil g = it.next();
g.hop();
}
}
}

import java.util.*;

import java.util.*;

class Gerbil {
private int gerbilNumber;
public Gerbil(int i) {
gerbilNumber = i;
}
public void hop() {
System.out.println("Gerbil " + gerbilNumber + " hops");
}
}

public class Test {
public static void main(String[] args) {
ArrayList<Gerbil> gerbils = new ArrayList<Gerbil>();
Iterator<Gerbil> it = gerbils.iterator(); // Chodzi o tą linijkę
for(int i = 0; i < 10; i++)
gerbils.add(new Gerbil(i));
while (it.hasNext()) {
Gerbil g = it.next();
g.hop();
}
}
}

Aby zadziałało w 2 wersji należy wpisać przed
while (it.hasNext()) {
kod:
it = gerbils.iterator();

Tylko dlaczego, przecież inicjowalem zmienna it predzej?

0

W drugim przykładzie zmieniasz kolekcję (dane) po utworzeniu iteratora. To jest niedozwolone.

0

Żeby nie sypało wyjątkiem, możesz użyć kolekcji z java.util.concurrent.

0

No pod wzgledem wydajnosciowym swietny pomysl. Moze w ogole niech kopiuje cala kolekcje przed wywolaniem kazdej metody? Dobijaja mnie takie posty.

0

Nie, mój pomysł jest jednak lepszy.
Nie chodzi mi o to, że lepiej jest użyć copyonwrite'a niż zamienić linijki kolejnością, ale dla zadań wielowątkowych, w odpowiednich przypadkach (które opisuje dokumentacja), gdzie istnieje ryzyko ConcurrentModificationException, to rozwiązanie jest na pewno lepsze niż jakieś kombinowanie. Ja tylko mówię, jak pozbyć się wyjątku.

0

@iooi napisał

Nie, mój pomysł jest jednak lepszy

Od czego on jest lepszy?

0
iooi napisał(a)

Ja tylko mówię, jak pozbyć się wyjątku.

No wlasnie - bez sensu odpowiedz. Nie tylko o to chodzi zeby pozbyc sie tego wyjatku, ale zeby to zrobic poprawnie i z glowa. To co zaproponowales dla tego przykladu jest strasznie glupie. To co ja napisalem jeszcze glupsze, ale nie zczailes sarkazmu.
Odpowiedz bo jest w 100% wystarczajaca i najlepsza w kontekscie tego zadania.

0
http://download-llnw.oracle.com/javase/6/docs/api/java/util/concurrent/CopyOnWriteArrayList.html#iterator() napisał(a)

The returned iterator provides a snapshot of the state of the list when the iterator was constructed.

Zapewne nie o takie zachowanie chodziło autorowi.

Możliwe, że klasa java.util.concurrent.ConcurrentSkipListSet<E> ma funkcjonalność odpowiadającą autorowi.

0
bo napisał(a)

Od czego on jest lepszy?
Od kopiowania całej kolekcji przed wywołaniem każdej metody.
Jeśli ty, ::. - to ucilala, to zczaiłem - a ty nie zczaiłeś mojego. Powtarzam, że nie proponuję autorowi wykorzystania tego w tym konkretnym przypadku, ale obczajenie tego pakietu - bo to na pewno pomoże zrozumieć różnice pomiędzy sposobami iterowania w różnych kolekcjach i dlaczego tu sypie wyjątkiem, a tam by nie sypało (niekoniecznie w CopyOnWriteArrayList).

1 użytkowników online, w tym zalogowanych: 0, gości: 1