Vor 3 Jahren wurde eine ähnliche Frage hier gestellt: Gibt es ein Java-Äquivalent von Pythons Enumerate-Funktion?
Ich schätze die listIterator()
Lösung sehr. Dennoch arbeite ich heute viel mit den neuen Streams und Lambdas (eingeführt in JDK 8) und frage mich: Gibt es eine elegante Möglichkeit, den Index des aktuell bearbeiteten Elements zu erhalten? Meins ist unten dargestellt, aber ich finde es nicht besonders attraktiv.
Diese Frage wurde schon einige Male gestellt. Die Schlüsselbeobachtung ist, dass, wenn Sie keine perfekte Größe und Splitting-Informationen haben (im Grunde genommen, wenn Ihre Quelle ein Array ist), dies eine sequenzielle Operation wäre.
Die "unappetitliche" Antwort, die Sie vorschlagen:
%Vor% ist tatsächlich ziemlich effizient, wenn myList
eine ArrayList
oder andere Liste mit einer schnellen O (1) indexed-get-Operation ist und sauber parallelisiert. Also ich denke, es ist nichts falsch daran.
Es kann einige Problemumgehungen geben.
Sie können eine AtomicInteger
verwenden, die Sie bei jedem Durchlauf eines Elementes des Streams erhöhen
Oder einen Iterator aus einem anderen Stream für die Indizes verwenden (ein bisschen wie Ihre ursprüngliche Idee), aber effizienter, da Sie get
nicht auf der Liste aufrufen.
Nun, ich bin nicht sicher, ob es andere schönere Alternativen gibt (sicherlich), aber das ist, was ich für den Moment denke.
Beachten Sie, dass davon ausgegangen wird, dass Sie keinen parallelen Stream verwenden. Im letzteren Fall wäre das nicht möglich, um eine Zuordnung der Elemente mit ihren ursprünglichen Indizes in der Liste zu erhalten.
Wenn Sie eine Lösung wollen, die auch mit Nicht- RandomAccess
Listen funktioniert, können Sie sich eine einfache Hilfsmethode schreiben:
Dann können Sie es wie folgt verwenden: forEach(list, (i,s)->System.out.println(i+"\t"+s));
Wenn Sie die Reihenfolge von Element und Index vertauschen, können Sie ein ObjIntConsumer
anstelle von BiConsumer<Integer,? super T>
, um möglichen Box-Overhead zu vermeiden:
Dann zu verwenden wie forEach(list, (s,i) -> System.out.println(i+"\t"+s));
...
Wenn Sie eine sauberere Syntax wünschen, schließen Sie einfach einige Ihrer Anrufe:
%Vor%Dann benutze es:
%Vor%Wenn Sie eine effiziente LinkedList-Lösung haben möchten, müssen Sie dies bewerkstelligen, ohne LinkedList.get () aufzurufen.