fail-fast Iteratoren nerven gewaltig

Status
Nicht offen für weitere Antworten.

0x7F800000

Top Contributor
Hallo allerseits.

Ich fang schon mal an zu labern und mich über alles mögliche zu beschweren, das hilft manchmal bei der Lösung eines Problems. :) Falls jemand was einwerfen kann: vorschläge sind immer willkommen! :toll:

Diesmal habe ich echt stress mit fail-fast Iteratoren. :autsch:
Kann mir bitte jemand sagen, wieso es dermaßen unmöglich sein soll, entspannt weiterhin über eine Liste zu iterieren, wenn unterwegs an's ende etwas angehängt wird? :(

Mir fällt langsam echt nichts mehr besseres ein, als alle Listen durch ArrayLists und alle ListIterators durch künstlich mitgeschleppten int-indizes zu ersetzen. Das gefällt mir überhaupt nicht. Denn es ist imho absolut unproblematisch, wenn ein Iterator eine Liste durchläuft, die ständig länger wird. Dem Iterator wird dadurch an keiner Stelle der Boden unter den Füßen weggerissen, wenn man es vorsichtig macht.

Gibt's irgendwo einen adequaten ersatz? ArrayLists mit ihrem bescheuerten allokieren-realokieren lösen bei mir Panikattaken aus, ich würde es sehr gerne mit normalen doppeltverketteten Listen machen. Was tun? ???:L
 

diggaa1984

Top Contributor
ich vermute mal das liegt eher daran, dass der Iterator schoen mit indizes arbeitet

Code:
/**
	 * Index of element to be returned by subsequent call to next.
	 */
	int cursor = 0;

	/**
	 * Index of element returned by most recent call to next or
	 * previous.  Reset to -1 if this element is deleted by a call
	 * to remove.
	 */
	int lastRet = -1;

und wenn du nun mittendrin was aenderst, löscht, einfügst weiss der geier was (mit normalen List-Methoden), dann kanns sein das du mit Iterator-Methoden ganz andere Ergebnisse bekommst als dir lieb ist (set, get, next etc.), also nicht das Element bearbeitest oder zurückgeben lässt, was du erwartest !?

Wenn man die Iterator-Methoden nutzt, dann werden diese 2 Variablen ja auch immer fein manipuliert :D

zu finden in: AbstractList<E>
 
G

Gelöschtes Mitglied 5909

Gast
Dem Iterator wird dadurch an keiner Stelle der Boden unter den Füßen weggerissen, wenn man es vorsichtig macht.

Du beantwortest deine Frage selbst.

Zur Lösung könntest du aber einen eigenen Iterator implementieren, der halt die indizes nimmt.

Da stellen sich mir spontan folgende Fragen:

- wann updatest du deine size im iterator?
- was machst du wenn einer remove() auruft?

Das und mehr kann zu inkonsistenz im Iterator und dadurch dann auch wieder in der Liste führen. Ich würde stattdessen warscheinlich eine zweite Liste verwenden und dann da drüber iterieren wenn die erste fertig ist (und ggf einen iterator schreiben der über mehrere Listen vom gleichen Typ iteriert)
 

0x7F800000

Top Contributor
raiL hat gesagt.:
Zur Lösung könntest du aber einen eigenen Iterator implementieren, der halt die indizes nimmt.
ohja... wenn ich nach Make it work, Make it right zu Make it fast übergehe, werde ich mir wohl "massacreutil"-package schreiben müssen. Aber momentan doch lieber nicht.

- wann updatest du deine size im iterator?
- was machst du wenn einer remove() auruft?
sehr gute fragen.
Wenn man irgendwas allgemeingültiges braucht sind diese Punkte unbedingt zu beachten. Aber ich brauche zB eine spezielle Liste bei der
1) kein zugriff durch mehrere threads sinnvoll ist, weil der algo auf dieser ebene prinzipiell nicht parallelisierbar ist
2) ich nur einfügen, niemals etwas entfernen will
Da ist es halt sehr frustrierend an die ganzen einschränkungen der API gebunden zu sein, die in meinem Fall nichts bringen sondern nur stressen... Naja, API ist ja nicht allmächtig. Werde mir später evtl selbst was passenderes schreiben :toll:

_____________________________________________________

Also, hab's jetzt sekundär-temporär (d.h. zum zweiten Mal temporär^^) durch eine halbwegs akzeptable implementierung mit einer ArrayList gelöst. Hässliche, nach außen unverständliche einschränkung, aber gut, passt für's erste... und zweite^^ :roll:

Danke an alle.
 
G

Gelöschtes Mitglied 5909

Gast

0x7F800000

Top Contributor
sicher auch eine option, aber umgangssprachlich fasse ich alles was nicht-standard-API ist als "selber basteln" zusammen ;)
Thx nochmal :toll:
 
G

Gelöschtes Mitglied 5909

Gast
Hab grade mal nachgeschaut und add ist implementiert. Dann müsstest du ja nur den Listiterator nehmen, sowohl ArrayList als auch LinkedList verwenden den (bzw erben von abstractlist)

Code:
    private class ListItr extends Itr implements ListIterator<E> {
	ListItr(int index) {
	    cursor = index;
	}

	public boolean hasPrevious() {
	    return cursor != 0;
	}

        public E previous() {
            checkForComodification();
            try {
                int i = cursor - 1;
                E previous = get(i);
                lastRet = cursor = i;
                return previous;
            } catch (IndexOutOfBoundsException e) {
                checkForComodification();
                throw new NoSuchElementException();
            }
        }

	public int nextIndex() {
	    return cursor;
	}

	public int previousIndex() {
	    return cursor-1;
	}

	public void set(E e) {
	    if (lastRet == -1)
		throw new IllegalStateException();
            checkForComodification();

	    try {
		AbstractList.this.set(lastRet, e);
		expectedModCount = modCount;
	    } catch (IndexOutOfBoundsException ex) {
		throw new ConcurrentModificationException();
	    }
	}
 

Marco13

Top Contributor
Dass ein Element am Ende angehängt wird, ist ein Spezialfall. Wenn das Anhängen während des Iterierens passiert, soll auch über die angehängten Elemente iteriert werden. Klar. Was denn sonst? Ja, ganz einfach was sonst: Vielleicht soll NICHT drüber iteriert werden!? Spätestens, wenn man irgendwo mittendrin was einfügen will, bekommt man Schwierigkeiten, das ganze "algebraisch sauber" zu beschreiben (es geht, sicher irgendwie, wäre aber vermutlich sch... kompliziert).

Wenn es um irgendeinen Spezialfall geht, kann vielleicht ein eigener Iterator eine Lösung sein - aber den mal kurz in der praktischen foreach-Schleife zu verwenden ist nicht so einfach. Ggf. kann man sich die Elemente, die Eingefügt/Angehängt werden sollen, auch merken, und sie anhängen, nachdem man fertigiteriert hat, oder so...
 

Ebenius

Top Contributor
So schwer ist das auch mit Iteratoren nicht:
Code:
final LinkedList<String> list = new LinkedList<String>();
list.addAll(Arrays.asList(new String[] { "A", "B", "C", "D", "E" }));
final int orgLen = list.size();
for (int startAtIndex = 0; startAtIndex < orgLen;) {
  final ListIterator<String> it = list.listIterator(startAtIndex);
  while (it.hasNext()) {
    final String element = it.next();
    if (element.matches("B|D")) {
      list.add("More: " + startAtIndex); // <-- your modification here
      break;
    }
  }
  startAtIndex = it.nextIndex();
}
:-D

Ebenius
 

Landei

Top Contributor
Ich fang schon mal an zu labern und mich über alles mögliche zu beschweren, das hilft manchmal bei der Lösung eines Problems.
In diesem Sinne:
Iteratoren sind insgesamt ein Krampf und zeigen, dass es Java ernsthaft an Ausdrucksfähigkeit mangelt. Sie hinter einem speziellen Sprachkonstrukt ("foreach"-Schleife) zu verstecken, macht die Sache nicht besser...
 

Ebenius

Top Contributor
Landei hat gesagt.:
Iteratoren sind insgesamt ein Krampf und zeigen, dass es Java ernsthaft an Ausdrucksfähigkeit mangelt. Sie hinter einem speziellen Sprachkonstrukt ("foreach"-Schleife) zu verstecken, macht die Sache nicht besser...
Wenn Blinde über Farbfernsehen reden... :roll:
 

Landei

Top Contributor
Ooooh ja!
Code:
val list = List(1,2,3,4,42)
list foreach println //List(1,2,3,4,42)
println(list.mkString(":")) //1:2:3:4:42
println(list.foldLeft(0)(_+_)) //52 <--Summe
println(list.reduceLeft(_+_)) //52 <--Summe
println(list.map((x:Int)=>x*x) //List(1,4,9,16,1764) <--Quadrate
println(list.map("" + _)) //List("1","2","3","4","42")
Und das ist nur die Spitze vom Eisberg...
 

byte

Top Contributor
Muss mir Scala echt mal angucken, bin aber meistens nicht mehr motiviert nach Feierabend. :cry:
 

Landei

Top Contributor
Ebenius hat gesagt.:
Landei hat gesagt.:
Iteratoren sind insgesamt ein Krampf und zeigen, dass es Java ernsthaft an Ausdrucksfähigkeit mangelt. Sie hinter einem speziellen Sprachkonstrukt ("foreach"-Schleife) zu verstecken, macht die Sache nicht besser...
Wenn Blinde über Farbfernsehen reden... :roll:

Wie soll ich das bitte verstehen? Das ich nicht weiß, wie ich einen Iterator schreibe oder benutze? Das habe ich schon oft genug - ich denke zu oft - gemacht. Iteratoren sind sicher ein Fortschritt gegenüber Indizes, aber für eine moderne Sprache einfach zu unhandlich, einseitig und langatmig. Wenn du Scala nicht magst, schau dir Ruby oder Groovy an.

Um bei den Zitaten zu bleiben:
Wenn man nichts außer einem Hammer hat, sieht jedes Problem wie ein Nagel aus.
 

0x7F800000

Top Contributor
Ebenius hat gesagt.:
LinkedList<?> list = ...
...
... list.listIterator(startAtIndex);
[/code]
ne, nich lustig :autsch:
dann mach ich das doch lieber gleich mit einer ArrayList, sieht genauso hässlich aus, aber da gibts den randomaccess in O(1) statt O(n) :roll:
 

Ebenius

Top Contributor
Andrey hat gesagt.:
dann mach ich das doch lieber gleich mit einer ArrayList, sieht genauso hässlich aus, aber da gibts den randomaccess in O(1) statt O(n) :roll:
Da haste recht. Ist von meinem ersten Ansatz übrig geblieben. :)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Input/Output BufferedStreamReader/InputStreamReader/ Eingabe = fail Java Basics - Anfänger-Themen 16
D JDBC Datenbank fail?! Java Basics - Anfänger-Themen 20
L Best Practice Code Refactoring für Methoden mit fast gleicher Aufbau Java Basics - Anfänger-Themen 6
D Wenn ich repaint(); mache, flackert es so stark, das man fast nichts erkennen kann. Java Basics - Anfänger-Themen 11
J Methoden Zwei Methoden die fast das gleiche tun organisieren Java Basics - Anfänger-Themen 3
F Alle DEMOS fast veraltet...? Java Basics - Anfänger-Themen 13
T Variablen fast identische Setter Java Basics - Anfänger-Themen 14
Z Speichern in eine .txt klappt.. fast Java Basics - Anfänger-Themen 23
E Projekt fast fertig, nur es läuft nicht ;) Java Basics - Anfänger-Themen 7
D Kann noch fast nichts, funktioniert auch fast nichts! Java Basics - Anfänger-Themen 8
Gama 2 (fast) gleiche Dateien - nur eine funktioniert Java Basics - Anfänger-Themen 2
P Welches Buch ist für Einsteiger(fast) ohne Vorwissen passend Java Basics - Anfänger-Themen 7
G ActionListener fast fertig Java Basics - Anfänger-Themen 7
N Mittelwert (fast fertig, nur noch 2 fehler ;-) ) Java Basics - Anfänger-Themen 14
F Frage zu Iteratoren Java Basics - Anfänger-Themen 2
walker23m C++ Listen iteratoren in Java umwandeln Java Basics - Anfänger-Themen 3
J Polymorphie Iteratoren statt Collections Java Basics - Anfänger-Themen 13
H Iteratoren funktionieren nicht Java Basics - Anfänger-Themen 4
B Datenstrukturen & Algorithmen => Iteratoren Java Basics - Anfänger-Themen 7
F Was sind Iteratoren ? Java Basics - Anfänger-Themen 9

Ähnliche Java Themen

Neue Themen


Oben