Core Java

Primitive Type Streams In Java

Introduction:

In this tutorial, we’ll learn how to use the Java 8 Streams API with the primitive data types. Java 8 Streams API is a powerful API to efficiently process a sequence of elements. If you wish to learn about Java 8 Streams API, please check out this tutorial.

Stream Over Java Primitives:

As we know, Streams API in general works with object types instead of primitives. However, the library provides support for the three most used primitive types – int, long and double. We have specialized stream classes – IntStream, LongStream, and DoubleStream in the library to support those primitive types. We can use IntStream for short, char, byte and boolean as well. To deal with float types, we can opt for DoubleStream.

To create an IntStream, we can either use the of() method in that class or the Arrays.stream() utility:

IntStream intStream1 = IntStream.of(1, 2, 3, 4, 5);
intStream1.forEach(System.out::println);

int[] arr = {1, 2, 3, 4, 5};
IntStream intStream2 = Arrays.stream(arr);
intStream2.forEach(System.out::println);

IntStream intStream3 = Arrays.stream(arr, 0, 2);
intStream3.forEach(System.out::println); //Only prints 1 and 2

For intStream3, we have passed the startIndex (inclusive) as well as endIndex (exclusive) to the Arrays.stream() method. It will print:

1
2

On the very same lines, we can also create a DoubleStream or a LongStream.

Arithmetic Operations:

The primitive stream supports max(), min(), sum() and average() operations:

int max = IntStream.of(1, 4, 6, 3, 7)
  .max()
  .getAsInt();

int min = IntStream.of(1, 4, 6, 3, 7)
  .min()
  .getAsInt();              

int sum = IntStream.of(1, 4, 6, 3, 7)
  .sum()
  .getAsInt();  

double avg = IntStream.of(1, 4, 6, 3, 7)
  .average()
  .getAsDouble();

Note that the methods – min(), max() and sum() returns an OptionalInt, so we have further used getAsInt() to retrieve the actual value. Similarly, average() method returns an OptionalDouble and so we’ll use getAsDouble() to get the calculated average value.

Working with Ranges:

The IntStream and LongStream provide the range() and rangeClosed() methods to help us work with a range of values:

IntStream.range(1, 10)
  .forEach(System.out::println); //Prints values from 1 - 9

IntStream.rangeClosed(1, 10)
 .forEach(System.out::println); //Prints values from 1 - 10

It’s important to remember the subtle difference between these two methods: end value is exclusive for the range() method whereas it is inclusive when using the rangeClosed() method.

DoubleStream doesn’t provide any such method to operate over a range.

Boxing and Unboxing Streams:

It’s possible to convert a primitive type stream into a stream of objects and vice-versa. We can use the boxed() method over a primitive stream to convert it to a stream of objects:

List<Integer> listOfIntegers = IntStream.rangeClosed(1, 5)
  .boxed()
  .collect(Collectors.toList());

As we know, we can’t directly collect a primitive stream output in a List. So, we have boxed it to a Stream<Integer> before collecting the result to a List.

Similarly, we can also convert a wrapper type stream like Stream<Integer>, Stream<Long> or Stream<Double> to its primitive stream. Rather any reduction operation like max(), min() etc aren’t supported by the stream over objects, so we first have to convert them to a primitive type stream:

int max = Arrays.asList(1, 4, 7, 3, 2)
  .stream()
  .mapToInt(t -> t)
  .max()
  .getAsInt();

We can either use mapToXxx() or flatMapToXxx() methods to transform a stream of objects to its compatible primitive stream. Here, Xxx could be Int, Long orDouble based on the type of primitive stream to be created.

Conclusion:

In this tutorial, we looked at how to define and work with primitive type stream in Java. We looked at supported arithmetic operations and the range methods provided by IntStream and LongStream. We also learned to transform a primitive type stream into its wrapper type and vice-versa.

Be the First to comment.

Leave a Comment

Your email address will not be published. Required fields are marked *