Java Stream diferencia entre mapa y mapToObj

3 minutos de lectura

avatar de usuario de masterofdisaster
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?

  • Sólo existen en los arroyos primitivos, donde map funciona para mapear el tipo primitivo a sí mismo, por ejemplo IntStream.map(IntOperator).

    – Luis Wasserman

    14 de diciembre de 2017 a las 7:10

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 IntStreamla 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 y Stream<Integer> y encaja en este patrón.

    – daniú

    14 de diciembre de 2017 a las 8:36

Avatar de usuario de Alex Mamo
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, LongStreamy DoubleStream) e interfaces funcionales especializadas primitivas (es decir, IntFunction, IntConsumer, IntSupplieretc.) para lograr un mejor rendimiento.

Una cosa más a tener en cuenta es que ninguna de las interfaces funcionales especializadas primitivas (como IntFunction, DoubleFunctiono IntConsumer) ampliar las interfaces funcionales no primitivas (es decir, Function, Consumery así).

java.util.function package contiene int, doubley long (pero no float) versiones de todas las interfaces funcionales. Por ejemplo, hay un IntFunctionuna función doble y una LongFunctionque son int, doubley long, versiones de Function. Estas funciones se utilizan junto con versiones primitivas especializadas de flujos como IntStream, DoubleStreamy 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 mapToIntque es cambiar el Stream escribe.

¿Ha sido útil esta solución?