This is best explained with a short example.
let's say this is my source observable that I want to filter
Observable.interval(1, TimeUnit.SECONDS)
I use a checkbox to handle the filter state. When the box is not checked, I want to skip all values.
I use RxAndroid to get an observable for the checkbox like this:
RxCompoundButton.checkedChanges(checkBox)
here is my code:
Observable.combineLatest(
RxCompoundButton.checkedChanges(checkBox)
, Observable.interval(1, TimeUnit.SECONDS)
, (isChecked, intervalCounter) -> {
if (!isChecked) {
return null;
} else {
return intervalCounter;
}
}
).filter(Objects::nonNull)
and I get the desired output
interval 1--2--3--4--5--6--7--8--9
checkbox 0-----1--------0-----1---
combineLatest
result ------3--4--5--------8--9
I am just getting started with RxJava and my "solution" does not feel right, because:
You can see that the combine function returns a magic value null
and then the filter will skip these nulls
.
That means that the filter function is called even though I already know, that I want to skip this data.
- maybe I should use another operator
- is there a way to use the checkbox-observable in a filter function
- maybe there is some way in the combine function to signal that I want to skip this data
Your pictures of the desired output is not correct. In your implementation
combineLatest
is combining anull
into the stream :IMHO, using
null
as a signal is not good in Rx Stream, developers can easily fall intoNullPointerException
.To avoid the use of
null
, there are two measures. The first one is to transform the result to a Pair, and apply filter & map later.A very simple
Pair
Class:Then the whole implementation would like this:
The data flow:
Or if you can Java 8 in your project, use
Optional
to avoidnull
, which is very similar to your solution but it gives the awareness for others developers that the Stream signal isOptional
.Some easier approach which is not same with
combineLatest
but identical to your desired result pictures.