maestro del desastre
No siento la diferencia entre map()
y mapToObj()
métodos en Java 8 Streams. En ambos podemos crear y devolver objetos a las secuencias, por lo que estos métodos existen como dos, no solo como uno.
¿Podrías darme la explicación con ejemplos?
Verás este patrón genial. los Stream
las clases incluyen un IntStream
, LongStream
, DoubleStream
etc. Esto es para que pueda usar tipos primitivos en operaciones de flujo. Porque de lo contrario tienes que usar Stream<Integer>
o Stream<Double>
que enmarcará los valores.
Del mismo modo, el map
Los métodos también hacen esto. En el Stream<T>
clase, hay mapToInt
, mapToDouble
métodos, pero la situación es un poco diferente en el IntStream
, DoubleStream
clases
En IntStream
la map
método toma un IntUnaryOperator
, que asigna un int a un int. Si desea asignar la transmisión a un Stream<T>
tienes que usar mapToObj
. mapToObj
es un buen nombre porque se distingue del map
que se asigna a ints. Significa que la corriente cambia de un IntStream
a un Stream<T>
. La razón por la cual mapToObj
se llama así es la misma razón por la cual mapToInt
se nombra así – para significar un cambio en el Stream
escribe/
-
Puede agregar una mención de la
boxed()
método que transfiere entre, por ejemplo,IntStream
yStream<Integer>
y encaja en este patrón.– daniú
14 de diciembre de 2017 a las 8:36
alex mamo
Las versiones primitivas y de objeto de los tipos de datos (es decir, int
y Integer
, double
y Double
, etc.) no son realmente compatibles entre sí en Java. Se hacen compatibles a través del paso adicional de auto-boxing/unboxing. Por lo tanto, si tiene un flujo de enteros primitivos y si intenta usar las versiones de objeto de Stream
y Function
(es decir Stream<Integer>
y Function<Integer, Integer>
), incurrirá en el costo de empaquetar y desempaquetar los elementos.
Para eliminar este problema, el paquete de funciones contiene versiones primitivas especializadas de flujos, así como interfaces funcionales. Por ejemplo, en lugar de usar Stream<Integer>
Deberías usar IntStream
. Ahora puede procesar cada elemento de la transmisión usando IntFunction
. Esto evitará el auto-boxing/unboxing por completo.
Por lo tanto, siempre que desee procesar flujos de elementos primitivos, debe utilizar los flujos primitivos especializados (es decir, IntStream
, LongStream
y DoubleStream
) e interfaces funcionales especializadas primitivas (es decir, IntFunction
, IntConsumer
, IntSupplier
etc.) para lograr un mejor rendimiento.
Una cosa más a tener en cuenta es que ninguna de las interfaces funcionales especializadas primitivas (como IntFunction
, DoubleFunction
o IntConsumer
) ampliar las interfaces funcionales no primitivas (es decir, Function
, Consumer
y así).
java.util.function package
contiene int
, double
y long
(pero no float
) versiones de todas las interfaces funcionales. Por ejemplo, hay un IntFunction
una función doble y una LongFunction
que son int
, double
y long
, versiones de Function. Estas funciones se utilizan junto con versiones primitivas especializadas de flujos como IntStream
, DoubleStream
y LongStream
.
Tomemos algunos ejemplos:
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
Como conclusión, la razón por la que podría usar mapToObj
es el mismo que podrías usar mapToInt
que es cambiar el Stream
escribe.
Sólo existen en los arroyos primitivos, donde
map
funciona para mapear el tipo primitivo a sí mismo, por ejemploIntStream.map(IntOperator)
.– Luis Wasserman
14 de diciembre de 2017 a las 7:10