707 Stimmen

Methoden zur Iteration über eine Liste in Java

Als relativ neuer Benutzer der Java-Sprache versuche ich mich mit all den Möglichkeiten (oder zumindest den nicht pathologischen) vertraut zu machen, wie man durch eine Liste (oder vielleicht andere Sammlungen) iterieren kann, und welche Vor- und Nachteile jede Methode hat.

Gegeben ein List list Objekt, kenne ich die folgenden Möglichkeiten, um durch alle Elemente zu iterieren:

Grundlegende for Schleife (natürlich gibt es auch entsprechende while / do while Schleifen)

// Nicht empfohlen (siehe unten)!
for (int i = 0; i < list.size(); i++) {
    E element = list.get(i);
    // 1 - Methoden des Elements aufrufen
    // 2 - 'i' verwenden, um indexbasierte Aufrufe von Methoden der Liste zu machen

    // ...
}

Anmerkung: Wie @amarseillan bemerkt hat, ist diese Form keine gute Wahl für die Iteration über Lists, da die tatsächliche Implementierung der get Methode möglicherweise nicht so effizient ist wie bei Verwendung eines Iterator. Zum Beispiel müssen LinkedList-Implementierungen alle Elemente vor i durchlaufen, um das i-te Element zu erhalten.

In obigem Beispiel gibt es für die Listenimplementierung keine Möglichkeit, "ihre Position zu speichern", um zukünftige Iterationen effizienter zu machen. Für ein ArrayList ist das nicht wirklich wichtig, weil die Komplexität / Kosten von get konstant sind (O(1)), während sie für ein LinkedList proportional zur Größe der Liste sind (O(n)).

Für weitere Informationen über die Rechenkomplexität der integrierten Collections-Implementierungen, schauen Sie sich diese Frage an.

Verbesserte for Schleife (gut erklärt in dieser Frage)

for (E element : list) {
    // 1 - Methoden des Elements aufrufen

    // ...
}

Iterator

for (Iterator iter = list.iterator(); iter.hasNext(); ) {
    E element = iter.next();
    // 1 - Methoden des Elements aufrufen
    // 2 - iter.remove() verwenden, um das aktuelle Element aus der Liste zu entfernen

    // ...
}

ListIterator

for (ListIterator iter = list.listIterator(); iter.hasNext(); ) {
    E element = iter.next();
    // 1 - Methoden des Elements aufrufen
    // 2 - iter.remove() verwenden, um das aktuelle Element aus der Liste zu entfernen
    // 3 - iter.add(...) verwenden, um ein neues Element in die Liste einzufügen
    //     zwischen element und iter->next()
    // 4 - iter.set(...) verwenden, um das aktuelle Element zu ersetzen

    // ...
}

Funktionales Java

list.stream().map(e -> e + 1); // Kann eine Transformationsfunktion für e anwenden

Iterable.forEach, Stream.forEach, ...

(Eine map-Methode aus der Stream-API von Java 8 (siehe Antwort von @i_am_zero).)

In Java 8 haben Sammlungsklassen, die Iterable implementieren (zum Beispiel alle Lists), nun eine forEach Methode, die anstelle der oben gezeigten for-Schleife verwendet werden kann. (Hier ist eine andere Frage, die einen guten Vergleich liefert.)

Arrays.asList(1,2,3,4).forEach(System.out::println);
// 1 - Methoden eines Elements aufrufen
// 2 - wäre ein Verweis auf das enthaltende Objekt erforderlich, um ein Element zu entfernen
//     (TODO: Bitte jemand bestätigen / verneinen)
// 3 - trennt funktional die Iteration von der Aktion ab,
//     die mit jedem Element ausgeführt wird.

Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
// Gleiche Möglichkeiten wie oben plus möglicherweise höhere
// Nutzung von Parallelität
// (Vorsicht: Als Konsequenz ist die Ausführungsreihenfolge nicht garantiert,
// siehe [Stream.forEachOrdered][stream-foreach-ordered] für weitere
// Informationen dazu).

Gibt es noch andere Möglichkeiten, wenn ja, welche?

(Übrigens, mein Interesse resultiert überhaupt nicht aus dem Wunsch, die Leistung zu optimieren; ich möchte nur wissen, welche Formen mir als Entwickler zur Verfügung stehen.)

6voto

Mario Rossi Punkte 7501

Ich weiß nicht, was du als pathologisch betrachtest, aber ich kann dir einige Alternativen geben, die du vielleicht noch nicht gesehen hast:

List sl= list ;
while( ! sl.empty() ) {
    E element= sl.get(0) ;
    .....
    sl= sl.subList(1,sl.size());
}

Oder seine rekursive Version:

void visit(List list) {
    if( list.isEmpty() ) return;
    E element= list.get(0) ;
    ....
    visit(list.subList(1,list.size()));
}

Außerdem eine rekursive Version des klassischen for(int i=0... :

void visit(List list,int pos) {
    if( pos >= list.size() ) return;
    E element= list.get(pos) ;
    ....
    visit(list,pos+1);
}

Ich erwähne sie, weil du "ziemlich neu in Java" bist und das könnte interessant sein.

2voto

Sudip Bhandari Punkte 1877

Sie können forEach ab Java 8 verwenden:

 List nameList   = new ArrayList<>(
            Arrays.asList("USA", "USSR", "UK"));

 nameList.forEach((v) -> System.out.println(v));

1voto

Dil. Punkte 1856

In java 8 können Sie die Methode List.forEach() mit einem lambda expression verwenden, um über eine Liste zu iterieren.

import java.util.ArrayList;
import java.util.List;

public class TestA {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add("Apfel");
        list.add("Orange");
        list.add("Banane");
        list.forEach(
                (name) -> {
                    System.out.println(name);
                }
        );
    }
}

1voto

shila mosammami Punkte 175

In Java 8 oder höher können Sie ein Hashset mit der forEach() Methode durchlaufen.

import java.util.HashSet;

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

         HashSet hSet = new HashSet();

         // Elemente zu Ihrem HashSet hinzufügen mit add()
         hSet.add("test1");
         hSet.add("test2");
         hSet.add("test3");

         // Über die Elemente des Hashsets iterieren
         hSet.forEach(x -> System.out.println(x));
         // Oder Sie können kürzer schreiben:
         hSet.forEach(System.out::println);
    }
}

0voto

BJYC Punkte 295

Richtig, es werden viele Alternativen aufgelistet. Am einfachsten und saubersten wäre es, einfach die verbesserte for-Anweisung wie unten gezeigt zu verwenden. Der Ausdruck ist von einem Typ, der iterierbar ist.

for ( FormalParameter : Expression ) Statement

Zum Beispiel, um durch die List ids zu iterieren, können wir einfach so vorgehen:

for (String str : ids) {
    // Etwas tun
}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X