5 min read

In this article by Ivan Morgillo, the author of RxJava Essentials, we will approach Observable filtering with RxJava filter(). We will manipulate a list on installed app to show only a subset of this list, according to our criteria.

(For more resources related to this topic, see here.)

Filtering a sequence with RxJava

RxJava lets us use filter() to keep certain values that we don’t want, out of the sequence that we are observing. In this example, we will use a list, but we will filter it, passing to the filter() function the proper predicate to include only the values we want.

We are using loadList() to create an Observable sequence, filter it, and populate our adapter:

private void loadList(List<AppInfo> apps) {
   mRecyclerView.setVisibility(View.VISIBLE);
 
   Observable.from(apps)
          .filter((appInfo) -> 
               appInfo.getName().startsWith("C"))            .subscribe(new Observer<AppInfo>() {                @Override                public void onCompleted() {                    mSwipeRefreshLayout.setRefreshing(false);                }                  @Override                public void onError(Throwable e) {                    Toast.makeText(getActivity(), "Something went
                     south!", Toast.LENGTH_SHORT).show();                    mSwipeRefreshLayout.setRefreshing(false);                }                  @Override                public void onNext(AppInfo appInfo) {                    mAddedApps.add(appInfo);                    mAdapter.addApplication(mAddedApps.size() - 1,
                  appInfo);                }            }); }

We have added the following line to the loadList() function:

.filter((appInfo) -> appInfo.getName().startsWith("C"))

After the creation of the Observable, we are filtering out every emitted element that has a name starting with a letter that is not a C. Let’s have it in Java 7 syntax too, to clarify the types here:

.filter(new Func1<AppInfo, Boolean>() {
   @Override
   public Boolean call(AppInfo appInfo) {
       return appInfo.getName().startsWith("C");
   }
})

We are passing a new Func1 object to filter(), that is, a function having just one parameter. The Func1 object has an AppInfo object as parameter type and it returns a Boolean object. The filter() function will return true only if the condition will be verified. At that point, the value will be emitted and received by all the Observers.

As you can imagine, filter() is critically useful to create the perfect sequence that we need from the Observable sequence we get. We don’t need to know the source of the Observable sequence or why it’s emitting tons of different elements. We just want a useful subset of those elements to create a new sequence we can use in our app. This mindset enforces the separation and the abstraction skills of our coding day life.

One of the most common use of filter() is filtering null objects:

.filter(new Func1<AppInfo, Boolean>() {
   @Override
   public Boolean call(AppInfo appInfo) {
       return appInfo != null;
   }
})

This seems to be trivial and there is a lot of boilerplate code for something that trivial, but this will save us from checking for null values in the onNext() call, letting us focus on the actual app logic.

As result of our filtering, the next figure shows the installed apps list, filtered by name starting with C:

RxJava Essentials

Summary

In this article, we introduced RxJava filter() function and we used it in a real-world example in an Android app.

RxJava offers a lot more functions allowing you to filter and manipulate Observable sequences. A comprehensive list of methods, scenarios and example are available in RxJava that will drive you in a step-by-step journey, from the basic of the Observer pattern to composing Observables and querying REST API using RxJava.

Resources for Article:


Further resources on this subject:


LEAVE A REPLY

Please enter your comment!
Please enter your name here