Skip to content
Oracle Certified Professional Java SE 17 Developer

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.

The Empty Stream – Streams

The Empty Stream

An empty stream can be obtained by calling the empty() method of the core stream interfaces. As the name implies, such a stream has no elements.

Click here to view code image

Stream<CD> cdStream = Stream.empty();                   // Empty stream of CD.
System.out.println(“Count: ” + cdStream.count());       // Count: 0
IntStream iStream = IntStream.empty();                  // Empty stream of int.
System.out.println(“Count: ” + iStream.count());        // Count: 0

The count() method is a terminal operation in the Stream<T> interface (p. 953). It returns the number of elements processed through the stream pipeline.

Using the null value to indicate that a stream is empty may result in a NullPointer-Exception. Therefore, using an explicit empty stream is highly recommended.

Streams from Specified Values

The two overloaded of() methods in the core stream interfaces create finite sequential ordered streams from data values that are specified as arguments.

In the code below, the single-argument of() method is called at (1), and the variable arity of() method is called at (2), both creating a stream of element type CD. The size of the streams created at (1) and (2) is 1 and 3, respectively. The stream pipeline comprising (3) and (4) filters the pop music CDs and prints their title at (4). The forEach() terminal operation at (4) applies its Consumer action to each pop music CD.

Click here to view code image

// From specified objects.
Stream<CD> cdStream1 = Stream.of(CD.cd0);                  // (1) Single-arg call.
Stream<CD> cdStream2 = Stream.of(CD.cd0, CD.cd1, CD.cd2);  // (2) Varargs call.
cdStream2.filter(CD::isPop)                                // (3)
         .forEach(cd -> System.out.println(cd.title()));   // (4)

The code below shows examples of using numeric values to create streams. The values specified at (1) and (2) are autoboxed to create a stream of objects. The declaration statements at (3) and (4) avoid the overhead of autoboxing when streams of numeric values are created. However, at (4), an implicit numeric conversion to double is applied to the non-double values.

Click here to view code image

// From specified numeric values.
Stream<Integer> integerStream1 = Stream.of(2017, 2018, 2019);        // (1)
Stream<? extends Number> numStream = Stream.of(100, 3.14D, 5050L);   // (2)
IntStream intStream1 = IntStream.of(2017, 2018, 2019);               // (3)
DoubleStream doubleStream = DoubleStream.of(100, 3.14D, 5050L);      // (4)

The variable arity of() method can be used to create a stream whose source is an array. Equivalently, the overloaded Arrays.stream() method can be used for the same purpose. In all cases below, the size of the stream is the same as the size of the array, except at (7). An int array is an object that is passed to the single-argument Stream.Of() method (creating a Stream<int[]>), and not the variable arity Stream.of() method. The int array is, however, passed to the variable arity IntStream.of() method at (8). Creating a stream from a numeric array is safer with the numeric stream interfaces or the Arrays.stream() method than the Stream.of() method.

Click here to view code image

// From an array of CDs.
Stream<CD> cdStream3 = Stream.of(CD.cdArray);                 // (1)
Stream<CD> cdStream4 = Arrays.stream(CD.cdArray);             // (2)
// From an array of Integer.
Integer[] integerArray = {2017, 2018, 2019};                  // (3)
Stream<Integer> integerStream2 = Stream.of(integerArray);     // (4)
Stream<Integer> integerStream3 = Arrays.stream(integerArray); // (5)
// From an array of int.
int[] intArray = {2017, 2018, 2019};                          // (6)
Stream<int[]> intArrayStream = Stream.of(intArray);           // (7) Size is 1.
IntStream intStream2 = IntStream.of(intArray);                // (8) Size is 3.
IntStream intStream3 = Arrays.stream(intArray);               // (9) Size is 3.

The Stream.of() methods throw a NullPointerException if the argument is null. The ofNullable() method, on the other hand, returns an empty stream if this is the case; otherwise, it returns a singleton stream.

Archives

  • July 2024
  • June 2024
  • May 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • October 2023
  • September 2023
  • May 2023
  • March 2023
  • January 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • July 2022
  • April 2022
  • March 2022
  • November 2021
  • October 2021
  • September 2021
  • July 2021
  • June 2021
  • March 2021
  • February 2021

Calendar

October 2022
M T W T F S S
 12
3456789
10111213141516
17181920212223
24252627282930
31  
« Sep   Nov »

Categories

  • Aspects of Streams, Revisited
  • Converting between Stream Types
  • Execution Mode of a Stream
  • Mapping between Numeric Streams
  • Oracle Exams
  • Selecting Distinct Elements

Copyright Oracle Certified Professional Java SE 17 Developer 2025 | Theme by noranebula | Proudly powered by noranebula