RxJava讓我們使用filter()方法來過濾我們觀測序列中不想要的值,在上一章中,我們在幾個例子中使用了已安裝的應用列表,但是我們只想展示以字母C開頭的已安裝的應用該怎么辦呢?在這個新的例子中,我們將使用同樣的列表,但是我們會過濾它,通過把合適的謂詞傳給filter()函數(shù)來得到我們想要的值。
上一章中loadList()函數(shù)可以改成這樣:
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 wrong!", Toast.LENGTH_SHORT).show();
mSwipeRefreshLayout.setRefreshing(false);
}
@Override
public void onNext(AppInfo appInfo) {
mAddedApps.add(appInfo);
mAdapter.addApplication(mAddedApps.size() - 1,appInfo);
}
});
}
我們從上一章中的loadList()函數(shù)中添加下面一行:
.fliter((appInfo -> appInfo.getName().startsWith("C"))
創(chuàng)建Observable完以后,我們從發(fā)出的每個元素中過濾掉開頭字母不是C的。為了讓這里更清楚一些,我們用Java 7的語法來實現(xiàn):
.filter(new Func1<AppInfo,Boolean>(){
@Override
public Boolean call(AppInfo appInfo){
return appInfo.getName().startsWith("C");
}
})
我們傳一個新的Func1對象給filter()函數(shù),即只有一個參數(shù)的函數(shù)。Func1有一個AppInfo對象來作為它的參數(shù)類型并且返回Boolean對象。只要條件符合filter()函數(shù)就會返回true。此時,值會發(fā)射出去并且所有的觀察者都會接收到。
正如你想的那樣,從一個我們得到的可觀測序列中創(chuàng)建一個我們需要的序列filter()是很好用的。我們不需要知道可觀測序列的源或者為什么發(fā)射這么多不同的數(shù)據(jù)。我們只是想要這些元素的子集來創(chuàng)建一個可以在應用中使用的新序列。這種思想促進了我們編碼中的分離性與抽象性。
filter()函數(shù)最常用的用法之一時過濾null對象:
.filter(new Func1<AppInfo,Boolean>(){
@Override
public Boolean call(AppInfo appInfo){
return appInfo != null;
}
})
這看起來簡單,對于簡單的事情有許多模板代碼,但是它幫我們免去了在onNext()函數(shù)調用中再去檢測null值,讓我們把注意力集中在應用業(yè)務邏輯上。
下圖展示了過濾出的C字母開頭的已安裝的應用列表。
http://wiki.jikexueyuan.com/project/rxjava/images/chapter4_1.png" alt="" />