Java streams 16. Filter, skip, or sort

An intermediate operation returns a Stream object that emits or not the same or modified value(s) of the same or different type than the stream source. In this installment, we will discuss intermediate operations that do not change either element value or type. They either just do not allow some elements to propagate downstream (filtering and skipping) or re-arrange the elements in a different order (sorting).

The other three groups of intermediate operations are peeking (using peek() operation reviewed in the previous installment), mapping (using map() operation), and generating another stream (using flatMap() operation). The last two we will discuss in the upcoming installments.

Filtering

This group includes operations that remove duplicate elements and select for further processing only those elements that pass certain criteria:

Stream<T> distinct(). Compares stream elements using method Object.equals(Object) and skips the duplicates.

Stream<T> filter(Predicate<T> predicate). Allows flowing downstream only those elements that result in true when processed by the provided Predicate function.

— default Stream<T> dropWhile(Predicate<T> predicate). Skips those first elements of the stream that result in true when processed by the provided Predicate function.

— default Stream<T> takeWhile(Predicate<T> predicate). Allows only those first elements of the stream to be processed that result in true when processed by the provided Predicate function.

For example:

  
  Stream.of("2", "4", "3", "4", "2")
        .distinct()
        .forEach(System.out::print);   //prints: 243

  Stream.of("2", "4", "3", "4", "2")
        .filter(s -> Objects.equals(s, "2"))
        .forEach(System.out::print);   //prints: 22

  Stream.of("2", "4", "3", "4", "2")
        .dropWhile(s -> Integer.valueOf(s) < 3)
        .forEach(System.out::print);   //prints: 4342

  Stream.of("2", "4", "3", "4", "2")
        .takeWhile(s -> Integer.valueOf(s) < 3)
        .forEach(System.out::print);   //prints: 2
     

Please, notice that the last two operations have default implementation in the Stream interface. It means that the objects that implement the Stream interface do not need to implement these two methods. They inherit the implementation from the interface automatically. But when they do provide their own implementation of these two methods, the default implementation in the interface gets overwritten.

Skipping

This group includes operations that skip some of the elements, thus not allowing them flowing downstream. It is similar to filtering, except there is no function used as a criterion for skipping:

Stream<T> skip(long n). Ignores the first n stream elements emitted by the Stream object.

Stream<T> limit(long n). Allows only the first n stream elements emitted by the Stream object to flow downstream.

For example:

   
  Stream.of("2", "4", "3", "4", "2")
        .skip(3)
        .forEach(System.out::print);  //prints: 42

  Stream.of("2", "4", "3", "4", "2")
        .limit(3)
        .forEach(System.out::print);  //prints: 243
   

Sorting

The following two intermediate operations sort the stream elements in a default or specified order:

Stream<T> sorted(). Sorts the stream elements in the natural order (according to
their implementation of the Comparable interface).

Stream<T> sorted(Comparator<T> comparator). Sorts the stream elements in the 
order according to the provided Comparator<T> object.

For example:

  
  
  Stream.of("2", "4", "3", "4", "2")
        .sorted().forEach(System.out::print);  //prints: 22344

  Stream.of("2", "4", "3", "4", "2")
        .sorted(Comparator.reverseOrder())
        .forEach(System.out::print);           //prints: 44322

  

Please, notice that these operations can be applied only to a finite stream because they cannot be finished until all the elements are emitted. Naturally, these operations create a lot of overhead and slow down the stream processing. It would be wise to use them only for finite small-size streams.

In the next post, we will talk about the intermediate operation map() that transforms each of the emitted elements by applying to it a specified function.

See other posts on Java 8 streams and posts on other topics.
You can also use navigation pages for Java stream related blogs:
— Java 8 streams blog titles
— Create stream
— Stream operations
— Stream operation collect()
The source code of all the code examples is here in GitHub

, ,

Send your comments using the link Contact or in response to my newsletter.
If you do not receive the newsletter, subscribe via link Subscribe under Contact.

Powered by WordPress. Designed by Woo Themes