Da ich etwas neu in der Java-Sprache bin, versuche ich mich mit allen (oder zumindest nicht pathologischen) Möglichkeiten vertraut zu machen, wie man eine Liste (oder vielleicht andere Sammlungen) durchläuft, sowie mit den Vor- oder Nachteilen der einzelnen.
Bei einem bestimmten List<E> list
Objekt kenne ich die folgenden Möglichkeiten, um alle Elemente zu durchlaufen:
Grundlegend für Schleife (natürlich gibt es auch Äquivalente while
/ do while
Schleifen)
// Not recommended (see below)!
for (int i = 0; i < list.size(); i++) {
E element = list.get(i);
// 1 - can call methods of element
// 2 - can use 'i' to make index-based calls to methods of list
// ...
}
Hinweis: Wie @amarseillan hervorhob, ist dieses Formular eine schlechte Wahl für die Iteration über List
s, da die tatsächliche Implementierung der get
Methode möglicherweise nicht so effizient ist wie bei Verwendung von a Iterator
. Beispielsweise müssen LinkedList
Implementierungen alle Elemente vor i durchlaufen, um das i-te Element zu erhalten.
Im obigen Beispiel gibt es keine Möglichkeit für die List
Implementierung, "ihren Platz zu speichern", um zukünftige Iterationen effizienter zu gestalten. Für a spielt ArrayList
es keine Rolle, denn die Komplexität / Kosten von get
sind konstante Zeit (O (1)), während sie für a LinkedList
proportional zur Größe der Liste (O (n)) sind.
Weitere Informationen zur rechnerischen Komplexität der integrierten Collections
Implementierungen finden Sie in dieser Frage .
Verbesserte for-Schleife ( in dieser Frage gut erklärt )
for (E element : list) {
// 1 - can call methods of element
// ...
}
Iterator
for (Iterator<E> iter = list.iterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// ...
}
ListIterator
for (ListIterator<E> iter = list.listIterator(); iter.hasNext(); ) {
E element = iter.next();
// 1 - can call methods of element
// 2 - can use iter.remove() to remove the current element from the list
// 3 - can use iter.add(...) to insert a new element into the list
// between element and iter->next()
// 4 - can use iter.set(...) to replace the current element
// ...
}
Funktionelles Java
list.stream().map(e -> e + 1); // Can apply a transformation function for e
Iterable.forEach , Stream.forEach , ...
(Eine Kartenmethode aus der Stream-API von Java 8 (siehe Antwort von @ i_am_zero).)
In Java 8-Auflistungsklassen, die Iterable
(z. B. alle List
s) implementieren , gibt es jetzt eine forEach
Methode, die anstelle der oben gezeigten for-Schleifenanweisung verwendet werden kann . (Hier ist eine andere Frage , die einen guten Vergleich bietet.)
Arrays.asList(1,2,3,4).forEach(System.out::println);
// 1 - can call methods of an element
// 2 - would need reference to containing object to remove an item
// (TODO: someone please confirm / deny this)
// 3 - functionally separates iteration from the action
// being performed with each item.
Arrays.asList(1,2,3,4).stream().forEach(System.out::println);
// Same capabilities as above plus potentially greater
// utilization of parallelism
// (caution: consequently, order of execution is not guaranteed,
// see [Stream.forEachOrdered][stream-foreach-ordered] for more
// information about this).
Welche anderen Möglichkeiten gibt es, wenn überhaupt?
(Übrigens, mein Interesse beruht überhaupt nicht auf dem Wunsch, die Leistung zu optimieren . Ich möchte nur wissen, welche Formulare mir als Entwickler zur Verfügung stehen.)
List
Schnittstelle spezifisch?