If you have gone through the post Stream API in Java 8 one thing you would have noticed is that Streams work on object references. They can’t work on primitive types because of that many times people use Stream<Integer>, Stream<Long> or Stream<Double> in order to wrap primitive types into a wrapper object.
In
Java Stream API Examples you see an example where integers are collected in Stream<Integer>. But, that is not
an efficient way to work with primitive types as you need to wrap them into wrapper objects. Instead you should use
primitive specializations of Stream like IntStream
, LongStream
, and DoubleStream
that can store primitive values.
Apart from int you can use IntStream for short, char, byte, and boolean. For float DoubleStream can be used.
Creating primitive type Streams in Java
-
You can use of() method to create primitive type Stream. It has two variants, for IntStream these two variants are-
- static IntStream of(int t)- Returns a sequential IntStream containing a single element.
- static IntStream of(int... values)- Returns a sequential ordered stream whose elements are the specified values.
As Example-
System.out.println("--- IntStream ---"); IntStream is = IntStream.of(3, 4, 5, 6); is.forEach(System.out::println);
Output
--- IntStream --- 3 4 5 6
It works the same way for LongStream and DoubleStream.
- Using Arrays.stream() method
You can use Arrays.stream() method to create primitive type Stream. It has two variants, for DoubleStream these two variants are-
- public static DoubleStream stream(double[] array)- Returns a sequential DoubleStream with the specified array as its source.
- public static DoubleStream stream(double[] array, int startInclusive, int endExclusive)- Returns a sequential DoubleStream with the specified range of the specified array as its source.
It works the same way for IntStream and LongStream.
Example of Arrays.stream()
System.out.println("--- DoubleStream ---"); double[] num = {3.0, 4.7, 5.2, 6.8}; DoubleStream numStream = Arrays.stream(num); numStream.forEach(System.out::println); System.out.println("--- With Specified range ---"); numStream = Arrays.stream(num, 0, 2); numStream.forEach(System.out::println);
Output
--- DoubleStream --- 3.0 4.7 5.2 6.8 --- With Specified range --- 3.0 4.7
In the second variant since second argument is 2 and the end index passed is exclusive so effective range for the stream is 0 – 1.
-
Using range() and rangeClosed() methods
- static IntStream range(int startInclusive, int endExclusive)- Returns a sequential ordered IntStream from startInclusive (inclusive) to endExclusive (exclusive) by an incremental step of 1.
- static IntStream rangeClosed(int startInclusive, int endInclusive)- Returns a sequential ordered IntStream from startInclusive (inclusive) to endInclusive (inclusive) by an incremental step of 1.
It works the same way for LongStream. Note that these methods will work with IntStream and LongStream, not provided for DoubleStream.
For example, if you want a stream with 1000 integers, 1 – 1000.
IntStream thousandInt = IntStream.rangeClosed(1, 1000);
Since you can create a range of numbers, these methods help with testing with large data. See an example in Parallel Stream in Java Stream API.
Transforming Stream to primitive type Stream
Stream interface provides methods mapToInt()
, mapToDouble()
and mapToLong()
that can be used to transform stream of objects to a stream of primitive types in Java.
Infact reduction operations such as average, sum, min (without specifying a comparator), max (without specifying a comparator) are not provided for Stream with object references. Since these operations are used quite frequently with streams so you will do this transformation using mapToxxx methods a lot if time.
For example, if you have a list of employee objects and you want to get the maximum salary you can do it using mapToInt method like this-
OptionalInt maxSalary = empList.parallelStream().mapToInt(e -> e.getSalary()).max();
If you want total amount given to all employees then you can sum the salaries like this-
int totalSalary = empList.parallelStream().mapToInt(e -> e.getSalary()).sum();
If you have noticed the first example returns the result of type OptionalInt. Methods that return result of type Optional in Stream with objects will return result of type OptionalInt, OptionalLong and OptionalDouble. In these classes there are specific methods like getAsInt(), getAsLong() and getAsDouble() rather than a generic get() method present in Optional class.
Transforming primitive type Stream to Stream of objects
All the primitive type Streams have boxed()
method that will return a Stream consisting of the elements of this
stream wrapped as object.
Thus used with DoubleStream, boxed() method will return a Stream consisting of the elements of this stream, each boxed to a Double i.e. Stream<Double>.
Same way for IntStream and LongStream you will get a Stream having elements of type Integer and Long respectively, i.e. Stream<Integer> and Stream<Long>. For example-
Stream<Integer> iStream = IntStream.of(3, 4, 5, 6).boxed();
That's all for this topic Primitive Type Streams in Java Stream API. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Java Advanced Tutorial Page
Related Topics
You may also like-
No comments:
Post a Comment