Gibt es einen Weg in Javas for-each-Schleife?
for(String s : stringArray) {
doSomethingWith(s);
}
um herauszufinden, wie oft die Schleife bereits verarbeitet wurde?
Abgesehen von der Verwendung der alten und bekannten for(int i=0; i < boundary; i++)
- Schleife ist das Konstrukt
int i = 0;
for(String s : stringArray) {
doSomethingWith(s);
i++;
}
der einzige Weg, einen solchen Zähler in einer for-each-Schleife verfügbar zu haben?
Type var = null; for (var : set) dosomething; if (var != null) then ...
Antworten:
Nein, aber Sie können Ihren eigenen Zähler bereitstellen.
Der Grund dafür ist , dass die für jede Schleife-intern nicht den Fall hat einen Zähler; Es basiert auf der Iterable- Schnittstelle, dh es verwendet eine
Iterator
Schleife durch die "Sammlung" - die möglicherweise überhaupt keine Sammlung ist und tatsächlich überhaupt nicht auf Indizes basiert (z. B. eine verknüpfte Liste).quelle
for(int idx=0, String s; s : stringArray; ++idx) doSomethingWith(s, idx);
each_with_index
Schleifenmethode fürEnumerable
in Ruby. Siehe apidock.com/ruby/Enumerable/each_with_indexfor
for (int i = 0; String s: stringArray; ++i)
Es geht auch anders.
Vorausgesetzt, Sie schreiben Ihre eigene
Index
Klasse und eine statische Methode, die eineIterable
Überinstanz dieser Klasse zurückgibt , können SieWo die Implementierung von
With.index
so etwas istquelle
Die einfachste Lösung besteht darin , einfach einen eigenen Zähler zu betreiben:
Der Grund dafür ist , weil es gibt keine tatsächliche Garantie , dass Elemente in einer Auflistung (die die Variante
for
iteriert) selbst hat einen Index oder sogar einen hat definierten Reihenfolge (einige Sammlungen können die Reihenfolge ändern , wenn Sie hinzufügen oder entfernen Elemente).Siehe zum Beispiel den folgenden Code:
Wenn Sie das ausführen, können Sie Folgendes sehen:
Dies zeigt zu Recht an, dass die Reihenfolge nicht als herausragendes Merkmal einer Menge angesehen wird.
Es gibt andere Möglichkeiten, dies ohne manuellen Zähler zu tun, aber es ist ein gutes Stück Arbeit zum zweifelhaften Vorteil.
quelle
Die Verwendung von Lambdas und funktionalen Schnittstellen in Java 8 ermöglicht das Erstellen neuer Schleifenabstraktionen. Ich kann eine Sammlung mit dem Index und der Sammlungsgröße durchlaufen:
Welche Ausgänge:
Was ich implementiert habe als:
Die Möglichkeiten sind endlos. Zum Beispiel erstelle ich eine Abstraktion, die eine spezielle Funktion nur für das erste Element verwendet:
Welches druckt eine durch Kommas getrennte Liste korrekt:
Was ich implementiert habe als:
Bibliotheken werden angezeigt, um diese Art von Dingen zu erledigen, oder Sie können Ihre eigenen rollen.
quelle
Java 8 führte die
Iterable#forEach()
/Map#forEach()
-Methode ein, die für vieleCollection
/Map
Implementierungen effizienter ist als die "klassische" for-each-Schleife. Auch in diesem Fall wird jedoch kein Index bereitgestellt. Der Trick hier ist,AtomicInteger
außerhalb des Lambda-Ausdrucks zu verwenden. Hinweis: Variablen, die im Lambda-Ausdruck verwendet werden, müssen effektiv endgültig sein. Deshalb können wir keine gewöhnlichen Variablen verwendenint
.quelle
Ich fürchte, das ist mit nicht möglich
foreach
. Aber ich kann Ihnen einen einfachen For-Loop im alten Stil vorschlagen :Beachten Sie, dass Sie über die List- Oberfläche Zugriff haben
it.nextIndex()
.(bearbeiten)
Zu Ihrem geänderten Beispiel:
quelle
Eine der Änderungen, die
Sun
in Betracht gezogen werden,Java7
besteht darin, den Zugang zum InnerenIterator
in foreach-Schleifen zu ermöglichen. Die Syntax lautet ungefähr so (wenn dies akzeptiert wird):Dies ist syntaktischer Zucker, aber anscheinend wurden viele Anfragen für diese Funktion gestellt. Aber bis es genehmigt ist, müssen Sie die Iterationen selbst zählen oder eine reguläre for-Schleife mit einem verwenden
Iterator
.quelle
Idiomatische Lösung:
quelle
Obwohl es so viele andere Möglichkeiten gibt, dasselbe zu erreichen, werde ich meinen Weg für einige unzufriedene Benutzer teilen. Ich verwende die Java 8 IntStream-Funktion.
1. Arrays
2. Liste
quelle
Wenn Sie einen Zähler in einer für jede Schleife benötigen, müssen Sie sich selbst zählen. Soweit ich weiß, gibt es keinen eingebauten Schalter.
quelle
Es gibt eine "Variante" zu pax 'Antwort ... ;-)
quelle
i=0; i++;
Ansatz?In Situationen, in denen ich den Index nur gelegentlich benötige, wie in einer catch-Klausel, verwende ich manchmal indexOf.
quelle
Die beste und optimierte Lösung besteht darin, Folgendes zu tun:
Wobei Typ ein beliebiger Datentyp sein kann und Typ ist die Variable, auf die Sie eine Schleife anwenden.
quelle
Ich bin ein wenig überrascht, dass niemand Folgendes vorgeschlagen hat (ich gebe zu, es ist ein fauler Ansatz ...); Wenn stringArray eine Liste ist, können Sie stringArray.indexOf (S) verwenden, um einen Wert für die aktuelle Anzahl zurückzugeben.
Hinweis: Dies setzt voraus, dass die Elemente der Liste eindeutig sind oder dass es keine Rolle spielt, ob sie nicht eindeutig sind (da in diesem Fall der Index der ersten gefundenen Kopie zurückgegeben wird).
Es gibt Situationen, in denen das ausreichen würde ...
quelle
Hier ist ein Beispiel, wie ich das gemacht habe. Dies erhält den Index für jede Schleife. Hoffe das hilft.
quelle