Konvertieren Stream IntStream
Habe ich das Gefühl, ich bin hier etwas fehlt. Ich fand mich dabei die folgenden
private static int getHighestValue(Map<Character, Integer> countMap) {
return countMap.values().stream().mapToInt(Integer::intValue).max().getAsInt();
}
Mein problem ist mit den dummen Konvertierung von Stream
zu IntStream
über die mapToInt(Integer::intValue)
Gibt es eine bessere Weise zu tun, die Konvertierung? all dies ist zu vermeiden, mit max()
aus Stream
, erfordert die übergabe eines Comparator
aber die Frage ist speziell auf die Konvertierung von Stream
zu IntStream
- Haben Sie sich überlegt mit
max(Comparator.<Integer>naturalOrder())
? - Und warum genau glaubst du, dass es dumm ist? Möchtest du wieder ein int, ist so dass .mapToInt() macht Sinn...
- weil ich denke, dass ich bin verschwenden einen Anruf zu autobox die Werte, denen würde müssen O(n) Operationen. Ich hoffe, ich kann das streamen als ein IntStream direkt
- Nein, da keine Werte in Collections oder Maps primitive; und Sie sind nicht die Boxen, sondern hier unboxing. Noch ist es nicht so teuer wie Sie denken. Ich habe einen echten use-case im Hinterkopf, aber es ist zu lange zu erklären, in einem einzigen Kommentar.
- Nein, bist du nicht zu tun alle Boxen -- die Werte sind schon boxed, du bist unboxing (was Sie tun müssen, zu tun ist Vergleich). Du machst es richtig. Du bist nicht die Kalkulation selbst alle vermeidbaren Berechnung; wenn Sie Tat es in eine einfache alte Schleife, würden Sie noch tun, mindestens so viele unbox Operationen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Aufgrund der type erasure, die
Stream
Umsetzung hat keine Kenntnis über die Art seiner Elemente und können nicht Ihnen weder, eine vereinfachtemax
Betrieb noch eine Umstellung aufIntStream
Methode.In beiden Fällen Bedarf es einer Funktion, einer
Comparator
oder eineToIntFunction
bzw., um den Vorgang auszuführen, mit dem unbekannten Typ der Referenz derStream
's-Elemente.Die einfachste form für den Betrieb, den Sie ausführen möchten
angesichts der Tatsache, dass die Natürliche Ordnung Komparator ist implementiert als singleton. Es ist also die einzige Komparator-bietet die chance, erkannt zu werden durch die
Stream
Umsetzung wenn es ist jede Optimierung hinsichtlichComparable
Elemente. Wenn es keine solchen Optimierung ist, wird es noch die Variante mit dem geringsten Speicherbedarf aufgrund seiner singleton Natur.Wenn Sie darauf bestehen, tut eine Umstellung der
Stream
zu einemIntStream
es gibt keine Möglichkeit, um die Bereitstellung einerToIntFunction
und es gibt keine vordefinierte singleton für eineNumber::intValue
Art der Funktion, also mitInteger::intValue
ist schon die beste Wahl. Sie schreiben konntei->i
statt, das ist kürzer, aber nur versteckt den unboxing-Vorgang dann.Merke ich, Sie versuchen zu vermeiden, einen Komparator, aber Sie könnte verwenden der built-in für diese durch die Bezugnahme auf
Integer.compareTo
:Oder wie @fge schlägt vor, mit
::compare
:get()
vielleichtorElse(0)
oderorElseThrow(...)
vielleicht "sicherer"?get()
denn ich war konzentriert sich mehr auf den Komparator Teil. Gute call.stream().mapToInt(Integer::intValue)
IST der beste Weg, bereitsAndere Weise, die Sie tun könnten, ist die Umrechnung mit einem lambda:
mapToInt(i -> i)
.Ob Sie sollten einen lambda-Ausdruck oder eine Methoden Referenz im detail diskutiert wird hier, aber die Zusammenfassung ist, dass Sie verwenden sollten, je nachdem, was Sie finden mehr lesbar.
Wenn die Frage ist "Kann ich vermeiden, durch converter während der Konvertierung von
Stream<T>
zuIntStream
?" eine mögliche Antwort wäre "Es gibt keine Möglichkeit in Java zu machen, wie conversion-Typ-sicher und machen es Teil derStream
- Schnittstelle zur gleichen Zeit".In der Tat-Methode wandelt
Stream<T>
zuIntStream
ohne Konverter könnte so ausgesehen:So wird es wohl genannt werden, auf
Stream<Integer>
und nicht andere Arten von streams. Aber da die streams sind lazy ausgewertet und aufgrund der type erasure (denken Sie daran, dassStream<T>
ist generisch) code wird nicht an der Stelle, wo Strom verbraucht wird, die möglicherweise weit von dermapToInt()
nennen. Und es wird nicht in einer Weise, die äußerst schwierig zu lokalisieren die Quelle des Problems.Angenommen, Sie haben code:
Wird es scheitern, auf
consumeIntStream()
Anruf mit:Mit diesem stacktrace sind Sie in der Lage, schnell zu identifizieren, dass das problem in
produceIntStream()
weilmapToInt()
genannt wurde auf den stream von der falschen Art?Natürlich kann man schreiben, die Umwandlung Methode, die geben Sie sicher, weil Sie akzeptiert Beton
Stream<Integer>
:aber es ist nicht sehr bequem, weil es bricht fluent interface Art des streams.
BTW:
Kotlin-Erweiterung-Funktionen ermöglichen das aufrufen, einige code, wie es ist ein Teil der Klasse " - Schnittstelle. So sind Sie in der Lage, um diese Art-die sichere Methode als
Stream<java.lang.Integer>
's Methode: