Ganz kurze Frage zur erweiterten For-Schleife

lisali hat gesagt.:
Ich bin noch neu bei Java, deswegen weiß ich leider noch nicht was eine LinkList ist im Vergleich zur ArrayList.

Na ja, eine ArrayList verwaltet die Daten intern als Array, welches sich selbst vergrößert.

Eine ArrayList ist zu wählen, sollte man keine Elemente aus der Mitte entfernen wollen, oder welche in die Mitte hinzufügen wollen, da die ArrayList bei soetwas langsam arbeitet.

Warum?
Die ArrayList müsste bei so einer Operation ein neues Array erstellen und den Inhalt des alten in ein neues kopieren.

Die ArrayList hat eine bessere Performance indem man wie du es oben gezeigt hast, eine for Schleife verwendet und die Elemente direkt über den Index anspricht.


Eine LinkedList verwaltet die Elemente, indem jedes Element auf das nächste Element "zeigt".
Wenn man bei so einer Liste also etwas aus der mitte löscht, zeigt das Element vor dem gelöschten einfach auf das nach dem gelöschten.

Also ist sie eine LinkedList besser geeignet, sollte man Elemente bearbeiten/hinzufügen/entfernen will die nicht am Anfang oder Ende stehen.

Diese Art Liste sollte man umbedingt mit einem Iterator durchlaufen.


Bitte beachte, dass die Performanceunterschiede erst ab größeren Datenmengen merkbar sind.
Dennoch sollte man immer die richtige Art von List wählen.
 
Zuletzt bearbeitet:
Eine LinkedList ist (von außen) quasi das selbe, nur schreiben/löschen ist schneller und Feldzugriff langsamer als bei einer Array.

Was genau meinst du mit "von außen"?

Na ja, eine ArrayList verwaltet die Daten intern als Array, welches sich selbst vergrößert.

Eine ArrayList ist zu wählen, sollte man keine Elemente aus der Mitte entfernen wollen, oder welche in die Mitte hinzufügen wollen, da die ArrayList bei soetwas langsam arbeitet.

Die ArrayList hat eine bessere Performance indem man wie du es oben gezeigt hast, eine for Schleife verwendet und die Elemente direkt über den Index anspricht.

Eine LinkedList verwaltet die Elemente, indem jedes Element auf das nächste Element "zeigt".
Wenn man bei so einer Liste also etwas aus der mitte löscht, zeigt das Element vor dem gelöschten einfach auf das nach dem gelöschten.

Diese Art Liste sollte man umbedingt mit einem Iterator durchlaufen.

Bitte beachte, dass die Performanceunterschiede erst ab größeren Datenmengen merkbar sind.

Okay, danke für die Erklärung. Vorhin fiel mir dazu noch eine Frage ein, die mir wieder jetzt in den Sinn kommt, wegen dem hasNext().

Wenn die Liste leer ist und man das mit hasNext() bzw. dem Iterator prüft, kann es nicht zu Exceptions kommen, oder? Hoffe das ist keine blöde Frage.


Edit: Achja und in welchen Fällen benutzt oder bevorzugt man eher die LinkedList der ArrayList und wann diese VectorList eigentlich?
 
Hallo!

hasNext() liefert einfach false, wenn keine Elemente vorhanden sind.

Ein aufruf von next() danach wird mit einer Exception bestraft.

mfg
Martin.

Edit:

...bevorzugt man eher die LinkedList der ArrayList und wann diese VectorList eigentlich?

Es hängt davon ab was du machen willst.

Ein Vector ist threadsafe, kann also von konkurrierenden Threads ohne Nebeneffekten bearbeitet werden.
Will man threadsichere Lists, und andere Collections, kann man die synchronizedXXX Methoden der Klasse Collections benutzen.

So weit bist du aber noch nicht...

Wenn du nicht vor hast deine ArrayList zu bearbeiten (aus der Mitte löschen und in die Mitte einfügen), kannst du bei dieser bleiben.
 
Zuletzt bearbeitet:
Einfach von deiner Benutzer/coderebene aus.
Doch, wenn man Zugreift fliegt eine NoSuchElementException, aber hasNext() verhindert das Ausführen der while.
Den Einsatz von LinkedList hat mccae schon gesagt.

Vector weiß ich nicht, aber ich denke dass kommt aus einer älteren Version für Abwärtskompatiblität.


Edit: Ok, ich überlasse dir den Thread, sonst wird das hier unüberschaubar. >_<
 
Aber zum Aufruf bzw. zur Ausführung des Body's, wenn ich mit hasNext() prüfe, kommt es ja dann sowieso nicht, dass eine Exception gar nicht in Frage kommen kann, oder?

Also, bevorzugt man LinkedList immer nur dann eher der ArrayList, wenn man davon ausgehen kann, dass Daten im Wertebereich bzw. Element-Index, weit entfernt des Start- bzw. End-Indezes zu ändern sind? Eben weil das Array eine neues Array erstellen muss nicht wie bei der LinkedList?
Oder was genau meint man sonst mit "Mitte"?
Also, ich versteh das so,dass ich z.B. ein Array hab mit über 1000 Elementen und die Mitte wäre dann einfach irgendwo weit vom Ende der Liste?
Aber kann man nciht eigentlich einfach einen Eintrag leicht "überschreiben" mit Angabe der Index-Nummer?

list.add(50,"bla");

?

Spielt bei dem ganzen eine VectorList nochmal eine ganz andere Rolle oder wobei zieht man die in Betracht?
 
Hallo,

ich wollte schon sagen, bevor ihr euch hier über den Iterator auslasst, aber das ist ja schon zu spät. ;-)

Wenn die foreach-Schleife benutzt wird (wie oben) wird intern der Iterator verwendet. Also kann man beruhigt diese Schleife benutzen, wenn man den Iterator benutzen möchte.


Gruß

Sascha
 
Also.

Eine Exception kommt nicht in Frage, da ja die Schleife vorher beendet wird.

So lange du die Liste nicht von mehreren Threads aus bearbeitest, wird nichts schief gehen.

Mit "Mitte" meine ich: "Nicht am Anfang und nicht am Ende".
Also nicht 0 und nicht "size" oder "length".

Elemente in der "Mitte" überschreiben geht, jedoch wird's bei einer ArrayList langsam wenn du zum Beispiel Element 50 entfernen willst, da dann wieder ein neues Array erstellt werden muss.

Oder wenn du ein Element zwischen 49 und 50 einsetzen willst.
Dann muss auch ein neues Array erstellt werden.

Eine LinkedList würde einfach die virtuellen Zeiger (ich explizit virtuell, da es in Java soetwa wie Pointer nicht gibt) ändern.

In dem Fall würde 49 auf das neue Element zeigen, und das neue Element auf 50.
Würde man Element 50 löschen wollen, würde Element 49 dann auf Element 51 zeigen (welches dann zum Element 50 wird)

Bei einem Vector (es gibt keine VectorList) handelt es sich um eine alte implementierung einer Collection.

Einen Vector zieht man in betracht wenn man Wert auf Threadsicherheit legt.

Darauf einzugehen würde jetzt Seiten füllen.
Wenn du anfängst mit Threads zu arbeiten, wirst du dich früher oder später mit Problemen des gleichzeitigen Zugriffs auf eine Ressource auseinandersetzen müssen....

Du solltest dennoch die Collections wie List, Set und Map benutzen.
 
Hallo,

ich wollte schon sagen, bevor ihr euch hier über den Iterator auslasst, aber das ist ja schon zu spät. ;-)

Wenn die foreach-Schleife benutzt wird (wie oben) wird intern der Iterator verwendet. Also kann man beruhigt diese Schleife benutzen, wenn man den Iterator benutzen möchte.


Gruß

Sascha


Und wenn ich z.B. in der Liste überprüfen möchte, dass ein gewisser Eintrag rausfliegt mit if (list.contains("A")), kann ich das doch eigentlich nur mit der "normalen" for-Schleife machen, oder? Weil ich doch keine Index-Nummer bzw. Schleifendurchgangs-Nummer habe, um z.B. zu sagen list.remove(i) ?!
 
Zuletzt bearbeitet von einem Moderator:
Und wenn ich z.B. in der Liste überprüfen möchte, dass ein gewisser Eintrag rausfliegt mit if (list.contains("A")), kann ich das doch eigentlich nur mit der "normalen" for-Schleife machen, oder? Weil ich doch keine Index-Nummer bzw. Schleifendurchgangs-Nummer habe, um z.B. zu sagen list.remove(i) ?!

Beim Iterator gibt es die remove() Methode die zumeist auch unterstützt wird.

Ausserdem kannst du dir den Index eines Objektes aus der Collection mit indexOf zurückgeben lassen und dann remove(index) aufrufen.
Allerdings sollte man dies nicht während eines Iterator durchlaufs machen :D

mfg
Martin
 
Zuletzt bearbeitet:
Also.

Eine Exception kommt nicht in Frage, da ja die Schleife vorher beendet wird.

So lange du die Liste nicht von mehreren Threads aus bearbeitest, wird nichts schief gehen.

Mit "Mitte" meine ich: "Nicht am Anfang und nicht am Ende".
Also nicht 0 und nicht "size" oder "length".

Elemente in der "Mitte" überschreiben geht, jedoch wird's bei einer ArrayList langsam wenn du zum Beispiel Element 50 entfernen willst, da dann wieder ein neues Array erstellt werden muss.

Oder wenn du ein Element zwischen 49 und 50 einsetzen willst.
Dann muss auch ein neues Array erstellt werden.

Eine LinkedList würde einfach die virtuellen Zeiger (ich explizit virtuell, da es in Java soetwa wie Pointer nicht gibt) ändern.

In dem Fall würde 49 auf das neue Element zeigen, und das neue Element auf 50.
Würde man Element 50 löschen wollen, würde Element 49 dann auf Element 51 zeigen (welches dann zum Element 50 wird)

Bei einem Vector (es gibt keine VectorList) handelt es sich um eine alte implementierung einer Collection.

Einen Vector zieht man in betracht wenn man Wert auf Threadsicherheit legt.

Darauf einzugehen würde jetzt Seiten füllen.
Wenn du anfängst mit Threads zu arbeiten, wirst du dich früher oder später mit Problemen des gleichzeitigen Zugriffs auf eine Ressource auseinandersetzen müssen....

Du solltest dennoch die Collections wie List, Set und Map benutzen.

Also, erstmal vielen Dank für deine Mühe mir das hier zu erklären. Das weiß ich echt zu schätzen, danke! Und das klingt auch alles sehr einleuchtend.

Aber ich habe es jetzt so verstanden, dass wenn ich z.B. weiß, dass ich "höchstens nur" was in einer List überschreiben möchte, kann ich die ArrayList nehmen. Sollte es jedoch dazu neigen, dass was gelöscht oder hinzugefügt wird (in der Mitte), sollte ich auf eine LinkedList zurückgreifen. Stimmt das? (Natürlich zusätzlich noch in Hinsicht darauf, dass es sich um ein Programm handelt, das riesig ist oder wo viel Resourcen verwendet werden oder so.)

Und das mit dem Zeiger verstehe ich auch, denke ich. Wenn was neues z.B. bei 50 eingefügt wird, wird die "alte" 50 zur 51, oder? Aber geht man bei einer Liste von 100 Elementen aus, verschiebt sich ja dann auch alles um 1?
 

Neue Beiträge

Zurück