Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java Stream difference between map and mapToObj

I don't feel the difference between map() and mapToObj() methods in Java 8 Streams. In both we can create and return objects to the streams, so why these methods exist as two, not only one.

Could you give me the explanation with examples?

like image 994
masterofdisaster Avatar asked Dec 14 '17 07:12

masterofdisaster


People also ask

What is difference between map and filter in Java stream?

Filter takes a predicate as an argument so basically you are validating your input/collection against a condition, whereas a map allows you to define or use a existing function on the stream eg you can apply String.

What is mapToObj in Java?

In Java, the mapToObj() method of the IntStream interface is used to return an object-valued stream. This stream has the results obtained by applying the implementation of the IntFunction functional interface.

What does stream () map do?

Stream map() in Java with examples Stream map(Function mapper) returns a stream consisting of the results of applying the given function to the elements of this stream. Stream map(Function mapper) is an intermediate operation. These operations are always lazy.

Can we use stream with map in Java?

Converting only the Value of the Map<Key, Value> into Stream: This can be done with the help of Map. values() method which returns a Set view of the values contained in this map. In Java 8, this returned set can be easily converted into a Stream of key-value pairs using Set. stream() method.


2 Answers

You will see this cool pattern. The Stream classes includes a IntStream, LongStream, DoubleStream etc. This is so that you can use primitive types in stream operations. Because otherwise you have to use Stream<Integer> or Stream<Double>, which will box the values.

Similarly, the map methods also do this. In the Stream<T> class, there are mapToInt, mapToDouble methods, but the situation is a little bit different in the IntStream, DoubleStream classes.

In IntStream, the map method takes an IntUnaryOperator, which maps an int to an int. If you want to map the stream to a Stream<T>, you have to use mapToObj. mapToObj is a good name because it distinguishes from the map that maps to ints. It signifies that the stream changes from a IntStream to a Stream<T>. The reason why mapToObj is named like so is the same reason why mapToInt is named like so - to signify a change in the Stream type/

like image 141
Sweeper Avatar answered Sep 17 '22 13:09

Sweeper


The primitive and object versions of data types (i.e. int and Integer, double and Double, etc.) are not really compatible with each other in Java. They are made compatible through the extra step of auto-boxing/unboxing. Thus, if you have a stream of primitive ints and if you try to use the object versions of Stream and Function (i.e. Stream<Integer> and Function<Integer, Integer>), you will incur the cost of boxing and unboxing the elements.

To eliminate this problem, the function package contains primitive specialized versions of streams as well as functional interfaces. For example, instead of using Stream<Integer>, you should use IntStream. You can now process each element of the stream using IntFunction. This will avoid auto-boxing/unboxing altogether.

Thus, whenever you want to process streams of primitive elements, you should use the primitive specialized streams (i.e. IntStream, LongStream, and DoubleStream) and primitive specialized functional interfaces (i.e. IntFunction, IntConsumer, IntSupplier, etc.) to achieve better performance.

One more thing to note is that none of the primitive specialized functional interfaces (such as IntFunction, DoubleFunction, or IntConsumer) extend the non-primitive functional interfaces (i.e. Function, Consumer, and so on).

java.util.function package contains int, double, and long (but no float) versions of all the functional interfaces. For example, there is an IntFunction, a DoubleFunction, and a LongFunction, which are int, double, and long, versions of Function. These functions are used along with primitive specialized versions of streams such as IntStream, DoubleStream, and LongStream.

Let's take some examples:

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 

As a conclusion, the reason you might use mapToObj is the same as you might use mapToInt, which is to change the Stream type.

like image 34
Alex Mamo Avatar answered Sep 18 '22 13:09

Alex Mamo