Ich spüre keinen Unterschied zwischen map()
und mapToObj()
Methoden in Java 8 Streams. In beiden können wir Objekte erstellen und an die Streams zurückgeben, also warum existieren diese Methoden als zwei, nicht nur als eine.
Können Sie mir die Erklärung anhand von Beispielen geben?
Sie werden dieses coole Muster sehen. Das Stream
Klassen beinhaltet a IntStream
, LongStream
, DoubleStream
usw. Dies ist so, dass Sie primitive Typen in Stream-Operationen verwenden können. Denn sonst muss man verwenden Stream<Integer>
oder Stream<Double>
wodurch die Werte eingerahmt werden.
Ebenso die map
Methoden tun dies auch. In dem Stream<T>
Klasse, es gibt mapToInt
, mapToDouble
Methoden, aber die Situation ist ein wenig anders in der IntStream
, DoubleStream
Klassen.
Im IntStream
das map
Methode dauert ein IntUnaryOperator
, das ein int auf ein int abbildet. Wenn Sie den Stream einem zuordnen möchten Stream<T>
müssen Sie verwenden mapToObj
. mapToObj
ist ein guter Name, weil er sich von der unterscheidet map
das auf ints abgebildet wird. Es bedeutet, dass sich der Strom von a ändert IntStream
zu einem Stream<T>
. Der Grund warum mapToObj
so heißt, ist der gleiche Grund warum mapToInt
wird so benannt – um eine Änderung in der zu bezeichnen Stream
Typ/
Die primitiven und Objektversionen von Datentypen (z int
und Integer
, double
und Double
, usw.) sind in Java nicht wirklich miteinander kompatibel. Sie werden durch den zusätzlichen Schritt kompatibel gemacht Auto-Boxing/Unboxing. Wenn Sie also einen Strom primitiver Ints haben und versuchen, die Objektversionen von zu verwenden Stream
und Function
(dh Stream<Integer>
und Function<Integer, Integer>
), entstehen Ihnen die Kosten für das Ein- und Auspacken der Elemente.
Um dieses Problem zu beseitigen, enthält das Funktionspaket primitive spezialisierte Versionen von Streams sowie funktionale Schnittstellen. Zum Beispiel anstatt zu verwenden Stream<Integer>
du solltest benutzen IntStream
. Sie können jetzt jedes Element des Streams mit verarbeiten IntFunction
. Dadurch wird das automatische Boxen/Unboxen vollständig vermieden.
Wann immer Sie also Streams primitiver Elemente verarbeiten möchten, sollten Sie die primitiven spezialisierten Streams (d. h IntStream
, LongStream
und DoubleStream
) und primitive spezialisierte funktionale Schnittstellen (dh IntFunction
, IntConsumer
, IntSupplier
usw.), um eine bessere Leistung zu erzielen.
Eine weitere Sache, die zu beachten ist, ist, dass keine der primitiven spezialisierten funktionalen Schnittstellen (wie z IntFunction
, DoubleFunction
oder IntConsumer
) erweitern die nicht-primitiven funktionalen Schnittstellen (dh Function
, Consumer
usw).
java.util.function package
enthält int
, double
und long
(aber nein float
) Versionen aller funktionalen Schnittstellen. Beispielsweise gibt es eine IntFunction
eine DoubleFunction und a LongFunction
welche sind int
, double
und long
, Versionen von Function. Diese Funktionen werden zusammen mit primitiven spezialisierten Versionen von Streams wie verwendet IntStream
, DoubleStream
und LongStream
.
Nehmen wir einige Beispiele:
Stream<Object> stream1 = Stream.of(1, 2, 3); //Will compile fine
IntStream intStream1 = IntStream.of(4, 5, 6); //Will compile fine
Stream<Object> stream2 = IntStream.of(4, 5, 6); //Does not compile
Stream<Object> stream3 = IntStream.of(4, 5, 6).mapToObj(e -> e); //mapToObj method is needed
IntStream intStream2 = Stream.of(4, 5, 6).mapToInt(e -> e); //mapToInt method is needed
Als Fazit der Grund, den Sie verwenden könnten mapToObj
ist das gleiche, das Sie verwenden könnten mapToInt
was die ändern soll Stream
Typ.
Sie existieren nur an den primitiven Strömen, wo
map
funktioniert für die Abbildung des primitiven Typs auf sich selbst, zIntStream.map(IntOperator)
.– Louis Wassermann
14. Dezember 2017 um 7:10 Uhr