After we can create and transform Observable, is good to know, how to filter emitted items and get only items, which we want or we expect.

Filtering functions filter emitted items of source Observable and return new Observable, which emits only items, which meet the condition of filtering function. Of course that functions are similar to classic filtering of Collections with Java stream api or (Guava)[https://github.com/google/guava].

Filtering to one item

In this section will look at filter functions, which filter Observable and return Observable with only one item.

First

As the name suggests it returns Observable with only one item, which was emitted as first.

Method variants: first(defaultValue), firstElement, firstOrError

Beware that each variation of the method returns Observable with the different Observer on subscribing. See the example for more info.

Observable<Integer> observable = Observable.range(1, 10);
observable.first(999).subscribe(new PrintSingleObserver());
observable.firstElement().subscribe(new PrintMaybeObserver());
observable.firstOrError().subscribe(new PrintSingleObserver());
On subscribe.
On success: 1
On subscribe.
On success: 1
On subscribe.
On success: 1

An example in case, where Observable is empty. Where we can see differences between each method variant.

observable = Observable.empty();
observable.first(999).subscribe(new PrintSingleObserver());
observable.firstElement().subscribe(new PrintMaybeObserver());
observable.firstOrError().subscribe(new PrintSingleObserver());
On subscribe.
On success: 999
On subscribe.
On completed.
On subscribe.
On error: NoSuchElementException: null

Last

Return Observable with only one item, which was emitted before complete.

Method variants: last(defaultValue), lastElement, lastOrError

Beware that each variation of the method returns Observable with the different Observer on subscribing. See the example for more info.

Observable<Integer> observable = Observable.range(1, 10);
observable.last(999).subscribe(new PrintSingleObserver());
observable.lastElement().subscribe(new PrintMaybeObserver());
observable.lastOrError().subscribe(new PrintSingleObserver());
On subscribe.
On success: 10
On subscribe.
On success: 10
On subscribe.
On success: 10

An example in case, where Observable is empty. Where we can see differences between each method variant.

observable = Observable.empty();
observable.last(999).subscribe(new PrintSingleObserver());
observable.lastElement().subscribe(new PrintMaybeObserver());
observable.lastOrError().subscribe(new PrintSingleObserver());
On subscribe.
On success: 999
On subscribe.
On completed.
On subscribe.
On error: NoSuchElementException: null

ElementAt

Return Observable with only one item, which was emitted as n-th value. If given index is out of bounds, IndexOutOfBoundsException is thrown.

Method variantions: elementAt(index), elementAt(index, defaultValue), elementOrError(index)

Observable<Integer> observable = Observable.range(1, 10);
observable.elementAt(2).subscribe(new PrintMaybeObserver());
observable.elementAt(2, 999).subscribe(new PrintSingleObserver());
observable.elementAtOrError(11).subscribe(new PrintSingleObserver());
On subscribe.
On success: 3
On subscribe.
On success: 3
On subscribe.
On error: NoSuchElementException: null

An example in case, where Observable is empty. Where we can see differences between each method variant.

observable = Observable.empty();
observable.elementAt(2).subscribe(new PrintMaybeObserver());
observable.elementAt(2, 999).subscribe(new PrintSingleObserver());
observable.elementAtOrError(11).subscribe(new PrintSingleObserver());
On subscribe.
On completed.
On subscribe.
On success: 999
On subscribe.
On error: NoSuchElementException: null

Filtering to n items

Functions in this section filter Observable and result Observable have always n items.

Take

Return Observable with first n emitted items of another Observable.

Observable<Integer> observable = Observable.range(1, 10);
observable.take(2).subscribe(new PrintObserver());
On subscribe.
On next: 1
On next: 2
On completed.

Example for empty Observable.

observable = Observable.empty();
observable.take(2).subscribe(new PrintObserver());
On subscribe.
On completed.

Example for Observable with error.

observable = Observable.error(new IllegalAccessException());
observable.take(2).subscribe(new PrintObserver());
On subscribe.
On error: IllegalAccessException: null

TakeLast

Return Observable with last n emitted items before complete is emitted.

Observable<Integer> observable = Observable.range(1, 10);
observable.takeLast(2).subscribe(new PrintObserver());
On subscribe.
On next: 9
On next: 10
On completed.

Example for empty Observable.

observable = Observable.empty();
observable.takeLast(2).subscribe(new PrintObserver());
On subscribe.
On completed.

Example for Observable with error.

observable = Observable.error(new IllegalAccessException());
observable.takeLast(2).subscribe(new PrintObserver());
On subscribe.
On error: IllegalAccessException: null

Filtering

Filtering functions in this section filter Observable and return Observable with the same or less count of source Observable.

Debounce

Emit value only if no value after time span is not emitted.

Subject<Integer> observable = PublishSubject.create();
observable.onNext(1);
observable.onNext(2);
observable.debounce(100, TimeUnit.MILLISECONDS).subscribe(new PrintObserver());
observable.onNext(3);
observable.onNext(4);
Thread.sleep(110);
observable.onNext(5);
Thread.sleep(110);
observable.onNext(6);
observable.onNext(7);
observable.onComplete();
On subscribe.
On next: 4
On next: 5
On next: 7
On completed.

This example shows how debounce works. Returned Observable from filter function will emit only last value, because before the end of the time period is emitted some next value.

Subject<Integer> observable = PublishSubject.create();
observable.onNext(1);
observable.onNext(2);
observable.debounce(100, TimeUnit.MILLISECONDS).subscribe(new PrintObserver());
observable.onNext(3);
Thread.sleep(90);
observable.onNext(4);
observable.onNext(5);
Thread.sleep(90);
observable.onNext(6);
observable.onNext(7);
observable.onComplete();
On subscribe.
On next: 7
On completed.

Distinct

Creating Observable, which will emit only items, which were not already emitted.

Observable<Integer> observable = Observable.just(1, 2, 3, 1, 4, 2, 5, 6);
observable.distinct().subscribe(new PrintObserver());
observable.distinct(integer -> integer % 3).subscribe(new PrintObserver());
On subscribe.
On next: 1
On next: 2
On next: 3
On next: 4
On next: 5
On next: 6
On completed.
On subscribe.
On next: 1
On next: 2
On next: 3
On completed.

Filter

Filter items by predicate. If the predicate is true, it will emit the item.

Observable<Integer> observable = Observable.range(1, 10);
observable.filter(integer -> integer % 2 == 0).subscribe(new PrintObserver());
On subscribe.
On next: 2
On next: 4
On next: 6
On next: 8
On next: 10
On completed.

IgnoreElements

Ignore all emitted items, so only complete or error will be emitted.

Observable<Integer> observable = Observable.range(1, 10);
observable.ignoreElements().subscribe(new PrintCompleteObserver());
On subscribe.
On completed.

Sample

Filter items by time Interval, where only last item in sample period is emitted. If no value was emitted by a source Observable in sample, also no item will be emitted.

Subject<Integer> observable = PublishSubject.create();
observable.onNext(1);
observable.onNext(2);
observable.sample(100, TimeUnit.MILLISECONDS).subscribe(new PrintObserver());
observable.onNext(3);
observable.onNext(4);
Thread.sleep(110);
observable.onNext(5);
Thread.sleep(110);
observable.onNext(6);
observable.onNext(7);
observable.onComplete();
On subscribe.
On next: 4
On next: 5
On completed.

Skip

Skip first n items of Observable.

Observable<Integer> observable = Observable.range(1, 10);
observable.skip(3).subscribe(new PrintObserver());
On subscribe.
On next: 4
On next: 5
On next: 6
On next: 7
On next: 8
On next: 9
On next: 10
On completed.

SkipLast

Skip n emitted items before complete emit.

Observable<Integer> observable = Observable.range(1, 10);
observable.skipLast(3).subscribe(new PrintObserver());
On subscribe.
On next: 1
On next: 2
On next: 3
On next: 4
On next: 5
On next: 6
On next: 7
On completed.