Fehler im algorithmus?

... komplette Frage anzeigen

3 Antworten

Innerhalb von Iteratoren (foreach und Verwandte) sollte man die Liste, über die iteriert wird, IMMER als schreibgeschützt behandeln, auch wenn der Compiler es nicht tut.

Wenn man per Zähler/Index über eine Liste iteriert und innerhalb des Schleifenkörpers Elemente löscht und/oder einfügt, sollte man den Index IMMER von oben nach unten laufen lassen - sonst kommt man allzu leicht durcheinander:

for (index=list.length-1; index>=0; index--) { ... };

(Es ist natürlich auch möglich, den Index vorwärts laufen zu lassen und bei Löschungen die Änderung entsprechend zu berücksichtigen - ich verwende hier eine while-Schleife, weil ich der Ansicht bin, dass auch die Zählvariable in einer for-Schleife für den Schleifenkörper als schreibgeschützt zu betrachten ist:

index=0;
while(index<list.length) {
elementEntfernt=false;
doStuff; // hierbei ggf. elementEntfernt setzen
// if(!elementEntfernt) { index++; ];
};

aber ich finde das wesentlich unübersichtlicher und damit schwerer zu warten.)

Antwort bewerten Vielen Dank für Deine Bewertung
Kommentar von iFeelOffended
21.09.2016, 14:38

wie genau behandel ich denn die Liste als schreibgeschützt? hab davon nch nie was gehört...

meinst du mit von oben nach unten durchgehen vom element mit dem größten wert in der Liste bis zum 0-ten Element?

0

Eins der Hauptprobleme bei deinem Algorithmus ist das mischen von Schleifen-Zugriffen:

Hast du eine Liste:

List<String> myElements = new ArrayList<>();

Und du durchläufst deine Liste via Iterator, sollte der Zugriff so aussehen:

Iterator<String> myElementsItr = myElements.iterator();
while (myElementsItr.hasNext() {
   String currentElement = myElementsItr.next();
}

Und nicht mit Index anfangen.

Antwort bewerten Vielen Dank für Deine Bewertung
Kommentar von iFeelOffended
21.09.2016, 16:27

Okay, aber warum ist es in der dritten Zeile so wichtig noch einmal

String currentElement = myElementsItr.next();

zu schreiben? oder war das jetzt nur ein Beispiel? weil das drumherum hab ich doch so ähnlich gemacht. Oder meinst du das damit ich befehle wie remove() o.Ä. dann im folgenden über currentElement.remove() mache? Sorry wenn ich das gerade nicht so ganz verstehe...

0

Dein Problem entsteht wahrscheinlich, weil du aus deiner ArrayList Elemente entfernst, während du darüber iterierst. Das vertragen ArrayLists nicht gut.

(Eine IndexOutOfBoundsException tritt auf, wenn du versuchst auf ein Array-Element zuzugreifen, indem du einen Index verwendest, den es nicht (mehr) gibt.)

Ich würde dir empfehlen, Löschentscheidung und Löschen zu trennen.

  1. Du iterierst über alle Elemente und merkst dir dann, welche du löschen möchtest.
  2. Danach (außerhalb der Schleife) nimmst du dann genau diese Element aus der ArrayList heraus.

Antwort bewerten Vielen Dank für Deine Bewertung
Kommentar von iFeelOffended
21.09.2016, 13:24

Hatte ich mir zwischenzeitlich auch gedacht, aber ListIterator ist doch genau dafür da, dass man das eben nicht so machen muss oder?

0

Was möchtest Du wissen?