Irgendeine Möglichkeit, eine Map wie "(k, v)" zu streamen, anstatt mit (entry) zu arbeiten?

8

Grundsätzlich suche ich nach einer Möglichkeit, die Arbeit mit

zu vermeiden %Vor%

und

%Vor%

ähnlich wie Map.forEach() .

Wenn ich nur einen Weg zur Arbeit als map.stream().filter((k,v) -> ) ... und so weiter bekommen könnte

Es scheint, dass die Schnittstelle BiConsumer heißt. Vielleicht mit einem Konverter zu BiConsumer oder einem Stream.generate () someway

    
Whimusical 24.03.2015, 17:40
quelle

3 Antworten

10

Da dies eine sich wiederholende Frage ist, werde ich eine vollständige Lösung in den Ring werfen. Es ist ein PairStream -Typ, der standardmäßig ein einfacher Wrapper um ein gewöhnliches Stream ist (obwohl interface ist, sind Alternativen möglich).

Es konzentriert sich auf die Bereitstellung der geeigneten Zwischenoperationen und der terminalen Operationen, die nicht einfach ausgeführt werden können, indem eine der Methoden keys() , values() oder entries() aufgerufen wird, um zu einem konventionellen Einzelelement Stream zurückzukehren eine Terminaloperation verketten. So ist beispielsweise PairStream.from(map).filterValue(predicate).keys().findAny() der direkte Weg, um einen Schlüssel zu erhalten, für den der zugeordnete Wert mit dem Prädikat übereinstimmt. filterValue ist eine bequeme Zwischenoperation und keys kehrt zurück zu einer normalen Stream , was eine beliebige Terminaloperation für die Schlüssel erlaubt.

Einige Beispiele

%Vor%

%Vor%

Hier ist die komplette Klasse (ich habe nicht alle Operationen getestet, aber das meiste ist einfach):

%Vor%     
Holger 25.03.2015, 11:21
quelle
9

Es ist ein bisschen bedauerlich, dass der Hauptweg zur Verarbeitung einer Karte mit Streams darin besteht, die Einträge der Karte zu streamen. Das heißt, Sie müssen die Schlüssel und Werte der Einträge extrahieren. Das ist etwas ausführlich, aber es ist nicht wirklich so schlimm. Dennoch könnte es sinnvoll sein, eine Art von Hilfsmethoden zu betrachten, die ein BiPredicate oder BiFunction so anpassen, dass sie in den Stufen filter oder map eines Karteneingabestreams verwendet werden können. Sie sehen so aus:

%Vor%

Sobald Sie diese haben, können Sie sie verwenden, um einen Map-Eintrag-Stream zu vereinfachen (?). Nehmen wir an, Sie haben Map<String,Integer> und möchten die Einträge auswählen, bei denen die Länge des Zeichenfolgenschlüssels größer als der Ganzzahlwert ist, und dann den Schlüssel und den Wert in eine Zeichenfolge formatieren. Konventionell würden Sie das tun:

%Vor%

Mit den obigen Hilfsfunktionen könnten Sie diese Pipeline wie folgt umschreiben:

%Vor%

OK, Sie speichern ein paar Zeichen. Lohnt es sich?

    
Stuart Marks 25.03.2015 06:21
quelle
6

Nein, es gibt keine Möglichkeit, dies zu tun; Stream funktioniert nur mit einem einzelnen Elementtyp. Es gibt keinen Weg um den getKey und getValue Ansatz.

(Streaming über die Tasten und Aufruf von get scheint aus Ihrer Sicht eigentlich nicht besser zu sein, und es ist wahrscheinlich, dass es weniger effizient ist.)

    
Louis Wasserman 24.03.2015 18:18
quelle