Collecting to a List

The method Stream.toList() implements a terminal operation that can be used to collect or accumulate the result of processing a stream into a list. Compared to the toArray() instance method, the toList() method is a default method in the Stream interface. The default implementation returns an unmodifiable list; that is, elements cannot be added, removed, or sorted. This unmodifiable list is created from the array into which the elements are accumulated first.

If the requirement is an unmodifiable list that allows null elements, the Stream.to-List() is the clear and concise choice. Many examples of stream pipelines encountered so far in this chapter use the toList() terminal operation.

Click here to view code image

List<String> titles = CD.cdList.stream().map(CD::title).toList();
// [Java Jive, Java Jam, Lambda Dancing, Keep on Erasing, Hot Generics]
titles.add(“Java Jingles”);          // UnsupportedOperationException!

Like any other mutable reduction operation, the toList() method does not terminate when applied to an infinite stream, unless the stream is converted into a finite stream.

default List<T> toList()

Accumulates the elements of this stream into a List, respecting any encounter order the stream may have. The returned List is unmodifiable (ยง12.2, p. 649), and calls to any mutator method will always result in an UnsupportedOperation-Exception. The unmodifiable list returned allows null values.

See also the toList() method in the Collectors class (p. 980).

The Collectors.toCollection(Supplier) method is recommended for greater control.

Functional Reductions Exclusive to Numeric Streams

In addition to the counterparts of the methods in the Stream<T> interface, the following functional reductions are exclusive to the numeric stream interfaces IntStream, LongStream, and DoubleStream. These reduction operations are designed to calculate various statistics on numeric streams.

In the methods below, NumType is Int, Long, or Double, and the corresponding numtype is int, long, or double. These statistical operations do not terminate when applied to an infinite stream:

numtype
 sum()

This terminal operation returns the sum of elements in this stream. It returns zero if the stream is empty.

OptionalDouble average()

This terminal operation returns an OptionalDouble that encapsulates the arithmetic mean of elements of this stream, or an empty Optional if this stream is empty.

Click here to view code image

NumType
SummaryStatistics summaryStatistics()

This terminal operation returns a NumTypeSummaryStatistics describing various summary data about the elements of this stream.

Summation

The sum() terminal operation is a special case of a functional reduction that calculates the sum of numeric values in a stream. The stream pipeline below calculates the total number of tracks on the CDs in a list. Note that the stream of CD is mapped to an int stream whose elements represent the number of tracks on a CD. The int values are cumulatively added to compute the total number of tracks.

Click here to view code image

int totNumOfTracks = CD.cdList
    .stream()                                     // Stream<CD>
    .mapToInt(CD::noOfTracks)                     // IntStream
    .sum();                                       // 42

The query below sums all even numbers between 1 and 100.

Click here to view code image

int sumEven = IntStream
    .rangeClosed(1, 100)
    .filter(i -> i % 2 == 0)
    .sum();                                       // 2550

The count() operation is equivalent to mapping each stream element to the value 1 and adding the 1s:

Click here to view code image

int numOfCDs = CD.cdList
    .stream()
    .mapToInt(cd -> 1)                            // CD => 1
    .sum();                                       // 5

For an empty stream, the sum is always zero.

Click here to view code image

double total = DoubleStream.empty().sum();        // 0.0

Leave a Reply

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