Sorted Streams – Streams
Sorted Streams
The sorted() intermediate operation can be used to enforce a specific encounter order on the elements of the stream. It is important to note that the data source is not sorted; only the order of the elements in the stream is affected when a stream is sorted. It is an expensive stateful operation, as state must be kept for all elements in the stream before making them available in the resulting stream.
The following methods are defined in the Stream<T> interface, but only the first method is defined in the IntStream, LongStream, and DoubleStream interfaces:
Stream<T> sorted()
Stream<T> sorted(Comparator<? super T> cmp)
Return a stream containing the elements of this stream, sorted according to natural order or according to total order defined by the specified comparator, respectively.
The first method requires that the elements implement the Comparable<T> interface.
The sorting operation provides a stability guarantee for ordered streams only— that is, duplicates of an element will be in their encounter order in the resulting stream.
This is a stateful intermediate operation that does not change the size of the stream or the stream element type, and enforces the sort order to be the encounter order of the resulting stream.
The Comparable<E> and Comparator<E> interfaces are covered in §14.4, p. 761, and §14.5, p. 769, respectively.
Example 16.7 illustrates the sorted() operation on streams. Printing the array at (1) and executing the stream pipeline at (2) shows that the order of the elements in the array and in the stream is positional order, as one would expect. The zero-argument sorted() method sorts in natural order, as in the pipeline at (3). It expects the stream elements to implement the Comparable<CD> interface. The sorted() method in the pipeline at (4) uses the reverse natural order to sort the elements.
The pipeline at (5) represents the query to find all jazz music CDs and sort them by their title. A comparator to compare by title is passed to the sorted() method. Finally, the pipeline at (6) finds CDs with eight or more tracks, and sorts them according to the number of tracks. An appropriate comparator that compares by the number of tracks is passed to the sorted() method.
It is instructive to compare the output showing the results from each pipeline in Example 16.7. The comparators in Example 16.7 are also implemented as lambda expressions, in addition to their implementation by the methods in the Comparator<E> interface.
Example 16.7 Sorting Streams
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class Sorting {
public static void main(String[] args) {
System.out.println(“(1) Positional order in the array:”);
CD[] cdArray = CD.cdArray;
System.out.println(Arrays.toString(cdArray)); // (1)
System.out.println(“(2) Positional order in the stream:”);
List<CD> cdsByPositionalOrder = // (2)
Arrays.stream(cdArray)
.toList();
System.out.println(cdsByPositionalOrder);
System.out.println(“(3) Natural order:”);
List<CD> cdsByNaturalOrder = // (3)
Arrays.stream(cdArray)
.sorted()
.toList();
System.out.println(cdsByNaturalOrder);
System.out.println(“(4) Reversed natural order:”);
List<CD> cdsByRNO = // (4)
Arrays.stream(cdArray)
// .sorted((c1, c2) -> -c1.compareTo(c2))
.sorted(Comparator.reverseOrder())
.toList();
System.out.println(cdsByRNO);
System.out.println(“(5) Only Jazz CDs, ordered by title:”);
List<String> jazzCDsByTitle = // (5)
Arrays.stream(cdArray)
.filter(CD::isJazz)
// .sorted((c1, c2) -> c1.title().compareTo(c2.title()))
.sorted(Comparator.comparing(CD::title))
.map(CD::title)
.toList();
System.out.println(jazzCDsByTitle);
System.out.println(“(6) No. of tracks >= 8, ordered by number of tracks:”);
List<CD> cds = // (6)
Arrays.stream(cdArray)
.filter(d -> d.noOfTracks() >= 8)
// .sorted((c1, c2) -> c1.noOfTracks() – c2.noOfTracks())
.sorted(Comparator.comparing(CD::noOfTracks))
.toList();
System.out.println(cds);
}
}
Output from the program (formatted to fit on the page):
(1) Positional order in the array:
[<Jaav, “Java Jive”, 8, 2017, POP>,
<Jaav, “Java Jam”, 6, 2017, JAZZ>,
<Funkies, “Lambda Dancing”, 10, 2018, POP>,
<Genericos, “Keep on Erasing”, 8, 2018, JAZZ>,
<Genericos, “Hot Generics”, 10, 2018, JAZZ>]
(2) Positional order in the stream:
[<Jaav, “Java Jive”, 8, 2017, POP>,
<Jaav, “Java Jam”, 6, 2017, JAZZ>,
<Funkies, “Lambda Dancing”, 10, 2018, POP>,
<Genericos, “Keep on Erasing”, 8, 2018, JAZZ>,
<Genericos, “Hot Generics”, 10, 2018, JAZZ>]
(3) Natural order:
[<Funkies, “Lambda Dancing”, 10, 2018, POP>,
<Genericos, “Hot Generics”, 10, 2018, JAZZ>,
<Genericos, “Keep on Erasing”, 8, 2018, JAZZ>,
<Jaav, “Java Jam”, 6, 2017, JAZZ>,
<Jaav, “Java Jive”, 8, 2017, POP>]
(4) Reversed natural order:
[<Jaav, “Java Jive”, 8, 2017, POP>,
<Jaav, “Java Jam”, 6, 2017, JAZZ>,
<Genericos, “Keep on Erasing”, 8, 2018, JAZZ>,
<Genericos, “Hot Generics”, 10, 2018, JAZZ>,
<Funkies, “Lambda Dancing”, 10, 2018, POP>]
(5) Only Jazz CDs, ordered by title:
[Hot Generics, Java Jam, Keep on Erasing]
(6) No. of tracks >= 8, ordered by number of tracks:
[<Jaav, “Java Jive”, 8, 2017, POP>,
<Genericos, “Keep on Erasing”, 8, 2018, JAZZ>,
<Funkies, “Lambda Dancing”, 10, 2018, POP>,
<Genericos, “Hot Generics”, 10, 2018, JAZZ>]
Leave a Reply