Streams from Arrays – Streams

Streams from Arrays

We have seen examples of creating streams from arrays when discussing the variable arity of() method of the stream interfaces and the overloaded Arrays.stream() methods earlier in the chapter (p. 893). The sequential stream created from an array has the same order as the positional order of the elements in the array. As far as numeric streams are concerned, only an int, long, or double array can act as the data source of such a stream.

The code below illustrates creating a stream based on a subarray that is given by the half-open interval specified as an argument to the Array.stream() method, as shown at (1). The stream pipeline at (2) calculates the length of the subarray.

Click here to view code image

Stream<CD> cdStream = Arrays.stream(cdArray, 1, 4);          // (1)
long noOfElements = cdStream.count();                        // (2) 3

The following overloaded static methods for building sequential ordered streams from arrays are defined in the java.util.Arrays class:

Click here to view code image

static <T> Stream<T> stream(T[] array)
static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive)

Create a finite sequential ordered Stream<T> with the specified array as its source. The stream created by the second method comprises the range of values given by the specified half-open interval.

Click here to view code image

static
NumType
Stream stream(
numtype
[] array)
static
NumType
Stream stream(
numtype
[] array,
                            int startInclusive, int endExclusive)

NumType is Int, Long, or Double, and the corresponding numtype is int, long, or double.

Create a finite sequential ordered NumTypeStream (which is either IntStream, LongStream, or DoubleStream) with the specified array as its source. The stream created by the second method comprises the range of primitive values given by the specified half-open interval.

Building a Numeric Stream with a Range

The overloaded methods range() and rangeClosed() can be used to create finite ordered streams of integer values based on a range that can be half-open or closed, respectively. The increment size is always 1.

The following static factory methods for building numeric streams are defined only in the IntStream and LongStream interfaces in the java.util.stream package.

Click here to view code image

static
NumType
Stream range(
numtype
 startInclusive,
numtype
 endExclusive)
static
NumType
Stream rangeClosed(
numtype
 startInclusive,
                               
numtype
 endInclusive)

NumType is Int or Long, and the corresponding numtype is int or long.

Both methods return a finite sequential ordered NumTypeStream whose elements are a sequence of numbers, where the first number in the stream is the start value of the range startInclusive and increment length of the sequence is 1. For a half-open interval, as in the first method, the end value of the range endExclusive is excluded. For a closed interval, as in the second method, the end value of the range endInclusive is included.

The range(startInclusive, endExclusive) method is equivalent to the following for(;;) loop:

Click here to view code image

for (int i = startInclusive; i < endExclusive; i++) {
  // Loop body.
}

When processing with ranges of integer values, the range() methods should also be considered on par with the for(;;) loop.

The stream pipeline below prints all the elements in the CD array in reverse. Note that no terminating condition or increment expression is specified. As range values are always in increasing order, a simple adjustment can be done to reverse their order.

Click here to view code image

IntStream.range(0, CD.cdArray.length)                                   // (1)
         .forEach(i -> System.out.println(cdArray[CD.cdArray.length – 1 – i]));

The following example counts the numbers that are divisible by a specified divisor in a given range of values.

Click here to view code image

int divisor = 5;
int start = 2000, end = 3000;
long divisibles = IntStream
    .rangeClosed(start, end)                                            // (1)
    .filter(number -> number % divisor == 0)                            // (2)
    .count();                                                           // (3)
System.out.println(divisibles);                                         // 201

The next example creates an int array that is filled with increment values specified by the range at (1) below. The toArray() method is a terminal operation that creates an array of the appropriate type and populates it with the values in the stream (p. 971).

Click here to view code image

int first = 10, len = 8;
int[] intArray = IntStream.range(first, first + len).toArray();         // (1)
System.out.println(intArray.length + “: ” + Arrays.toString(intArray));
//8: [10, 11, 12, 13, 14, 15, 16, 17]

The example below shows usage of two nested ranges to print the multiplication tables. The inner arrange is executed 10 times for each value in the outer range.

Click here to view code image

IntStream.rangeClosed(1, 10)                                 // Outer range.
         .forEach(i -> IntStream.rangeClosed(1, 10)          // Inner range.
                           .forEach(j -> System.out.printf(“%2d * %2d = %2d%n”,
                                                           i, j, i * j)));
}

We cordially invite the inquisitive reader to code the above examples in the imperative style using explicit loops. Which way is better is not always that clear-cut.

Leave a Reply

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