Gibt es ein Java 8-Äquivalent von Python-Enumeration?

8

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.

%Vor%     
Radosław Łazarz 22.05.2014, 22:07
quelle

5 Antworten

12

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.

    
Brian Goetz 23.05.2014, 00:41
quelle
5

Es kann einige Problemumgehungen geben.

Sie können eine AtomicInteger verwenden, die Sie bei jedem Durchlauf eines Elementes des Streams erhöhen

%Vor%

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.

%Vor%

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.

    
Alexis C. 22.05.2014 22:37
quelle
4

Wenn Sie eine Lösung wollen, die auch mit Nicht- RandomAccess Listen funktioniert, können Sie sich eine einfache Hilfsmethode schreiben:

%Vor%

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:

%Vor%

Dann zu verwenden wie forEach(list, (s,i) -> System.out.println(i+"\t"+s)); ...

    
Holger 23.05.2014 08:24
quelle
2

Das Python-Beispiel in dem von Ihnen angegebenen Link lautet:

%Vor%

Es gibt mehrere Möglichkeiten, um dieselbe Ausgabe mit Java 8 zu erreichen, zum Beispiel:

%Vor%

welche Ausgaben:

%Vor%     
assylias 23.05.2014 00:36
quelle
2

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.

    
Dane White 23.05.2014 01:34
quelle

Tags und Links