IntStream example

In Java 8, java.util.stream.IntStream was introduced to deal with primitive ints which brings a new way to solving old problems of finding max or largest value in array, find min or smallest value in array, sum all elements in array, and average of all values in array. These numeric reductions of max, min, sum and average make what used to be a hard tedious challenge or needing to find a outside library to the jdk now much simpler. If you are looking to apply these techniques the stream reduction example or IntSummaryStatistics, a specialized object for collecting statistics, show how to use them.

In these examples we will show common methods exposed by Intstream that deal with int-value elements. In addition to dealing with ints, DoubleStreams is a specialized class to deal with primitive double and LongStream for dealing with primitive type long.

builder

There are various ways to build a stream and IntStream has a builder that allows you to chain together calls to set up configuration followed by a build method that creates the stream. This code snippet below makes a call to the builder and then adds two primitive int values. It then calls the sum method to find the sum of the stream.

@Test
public void intstream_builder() {

    int sum = IntStream.builder().add(10).add(10).build().sum();

    assertEquals(20, sum);
}

concat

In the event where you have seperate streams, IntStream provides the ability to concat or combine streams together. To demonstrate this we created two streams via the builder, concatenated and then called the sum method.

@Test
public void intstream_concat() {

    IntStream first = IntStream.builder().add(10).build();
    IntStream second = IntStream.builder().add(10).build();

    IntStream third = IntStream.concat(first, second);

    assertEquals(20, third.sum());
}

empty

The IntStream.empty returns an empty sequential IntStream.

@Test
public void intstream_empty() {

    IntStream emptyStream = IntStream.empty();

    assertEquals(0, emptyStream.count());
}

generate

The IntStream.generate allows you to produce an infinite stream of values on demand. In the code snippet below we will generate 10 ints and then find the distinct elements which will return numeric 1.

@Test
public void intstream_generate() {

    OptionalInt one = IntStream.generate(() -> 1).limit(10).distinct()
            .findFirst();

    assertEquals(1, one.getAsInt());
}

iterate

Similar to the IntStream.generate, the IntStream.iterate will return an infinite sequential ordered IntStream. The first parameter to IntStream.iterate is the seed and in our case 0. It will iterate from 0 and for every element will add 3, so 0 + 3, 3 + 3 and so on. Since we apply the limit it will return 3 iterations thus returning 0, 3, 6.

@Test
public void intstream_iterate() {

    List<Integer> numbers = IntStream.iterate(0, n -> n + 3).limit(3)
            .boxed().collect(Collectors.toList());

    assertThat(numbers,
            contains(new Integer(0), new Integer(3), new Integer(6)));
}

of

The IntStream.of method returns a stream whose elements are specified. Below a stream will be initialized with 5,10 and then max taken which will return 10 as the unit test reads.

@Test
public void intstream_of() {

    OptionalInt max = IntStream.of(5, 10).max();

    assertEquals(10, max.getAsInt());
}

range

Although not as extensive as guava's ranges or rangemaps, IntStream.range returns a sequential IntStream for the range of int elements. IntStream.range first parameter is inclusive while the second is exclusive. Looking at this example, it will include 1 but not include 3.

@Test
public void intstream_range() {

    List<Integer> numbers = IntStream.range(1, 3).boxed()
            .collect(Collectors.toList());

    assertThat(numbers, contains(new Integer(1), new Integer(2)));
}

rangeClosed

The difference between IntStream.range and IntStream.rangeClosed is that the second parameter or end parameter is inclusive instead of exclusive. It the range is from 1, 2 and 3.

@Test
public void intstream_rangeClosed() {

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

    assertThat(numbers,
            contains(new Integer(1), new Integer(2), new Integer(3)));
}

Map to IntStream

This example will take an ArrayList of strings and then map them to an IntStream by passing Integer.parseInt. Then for testing purposes we will call IntStream.max which will return 3.

@Test
public void map_to_intstream() {

    List<String> integers = new ArrayList<String>();
    integers.add("1");
    integers.add("2");
    integers.add("3");

    OptionalInt intStream = integers.stream().mapToInt(Integer::parseInt)
        .max();

    assertEquals(3, intStream.getAsInt());
}

Convert to stream of objects

If you are looking to convert Instream to a stream of Integers, you can call boxed method which returns the elements in the stream each boxed to an Integer.

@Test
public void convert_to_stream_of_objects() {

    int[] numbers = { 1, 2, 3, 4, 5, 6 };

    List<Integer> listOfInteger = Arrays.stream(numbers).boxed()
            .collect(Collectors.toList());

    assertThat(
            listOfInteger,
            contains(new Integer(1), new Integer(2), new Integer(3),
                    new Integer(4), new Integer(5), new Integer(6)));

}

Specify default

OptionalInt is a specialized version of Optional. In the instance where you want to provide a default other than 0, you can call the OptionalInt.orElse. In this example, we want to find the max value of an empty list. Since there isn't any values present it will return 5.

@Test
public void provide_default() {

    List<String> integers = new ArrayList<String>();

    int optionalInt = integers.stream().mapToInt(Integer::parseInt)
            .max().orElse(5);

    assertEquals(5, optionalInt);
}