RxJava從入門到不離不棄(四)——過濾操作符

Android機動車發表於2018-08-22

RxJava中的過濾操作符,顧名思義,這類操作符主要用於對事件資料的篩選過濾,只返回滿足我們條件的資料。

我們試想一下這樣的一個需求,有一個學生集合,要求將其中成績不及格的學生過濾,返回成績合格的學生集合,如果平時一般會怎麼做呢?可能會這樣實現:

List<Student> newList = new ArrayList<>();
for (int i = 0; i < oldList.size(); i++) {
	if(oldList.get(i).getCore()>60){
		newList.add(oldList.get(i));
	}
}
複製程式碼

對於極度厭惡多層巢狀結構的我來說,實在不喜歡這樣的程式碼。這樣的思路,會隨著業務邏輯的複雜程度,變得越來越複雜。

還好有RxJava,之後的程式碼著實簡化了許多。

RxJava過濾類操作符主要包含

Filter、Take、TakeLast、TakeUntil、Skip、SkipLast、ElementAt、Debounce、Distinct、DistinctUntilChanged、First、Last等等。

先定義這樣一個資料集合:

List<Person> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
	list.add(new Person(i, "js" + i));
}
複製程式碼

filter

filter(Func1)用來過濾觀測序列中我們不想要的值,只返回滿足條件的值。

filter傳入Func1物件,第一個泛型是傳入的發射型別,第二個引數是boolean型別,表示是否過濾。

        Observable.from(list)
                .filter(new Func1<Person, Boolean>() {
                    @Override
                    public Boolean call(Person person) {
                        return person.getAge() > 10;
                    }
                })
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("filter", "call: " + person.toString());
                    }
                });
複製程式碼

take

take方法,傳入一整數n,表示只取前n個資料。

        Observable.from(list)
                .take(3)
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("take", "call: " + person);
                    }
                });
複製程式碼

takeLast

takeLast(int)同樣用一個整數n作為引數,只不過它發射的是觀測序列中後n個元素。

        Observable.from(list)
                .takeLast(3)
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("take", "call: " + person);
                    }
                });
複製程式碼

skip

skip(int)讓我們可以忽略Observable發射的前n項資料。

        Observable.from(list)
                .skip(3)
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("skip", "call: " + person);
                    }
                });
複製程式碼

skipLast

skipLast(int)忽略Observable發射的後n項資料。

        Observable.from(list)
                .skipLast(3)
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("skipLast", "call: " + person);
                    }
                });
複製程式碼

elementAt

elementAt(int)用來獲取元素Observable發射的事件序列中的第n項資料,並當做唯一的資料發射出去。

        Observable.from(list)
                .elementAt(3)
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("elementAt", "call: " + person);
                    }
                });
複製程式碼

first

first()顧名思義,它是的Observable只傳送觀測序列中的第一個資料項。

        Observable.from(list)
                .first()
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("first", "call: " + person);
                    }
                });
複製程式碼

last

last()只發射觀測序列中的最後一個資料項。

        Observable.from(list)
                .last()
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("first", "call: " + person);
                    }
                });
複製程式碼

distinct

distinct去除重複,有無參形式:

        Observable.just(2, 1, 2, 2, 3, 4, 3, 4, 5, 5)
                .distinct()
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer i) {
                        System.out.print(i + " ");
                    }
                });
複製程式碼

還可以傳入Func1物件,自己實現判斷邏輯:

        list.add(new Person(3, "js3"));
        Observable.from(list)
                .distinct(new Func1<Person, String>() {

                    @Override
                    public String call(Person p) {
                        return p.getName();
                    }
                })
                .subscribe(new Action1<Person>() {
                    @Override
                    public void call(Person person) {
                        Log.e("distinct", "call: " + person);
                    }
                });
複製程式碼

debounce

debounce操作符是對源Observable間隔期產生的結果進行過濾,如果在這個規定的間隔期內沒有別的結果產生,則將這個結果提交給訂閱者,否則忽略該結果,原理有點像光學防抖.

debounce(時間,時間單位)

 Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if (subscriber.isUnsubscribed()) return;
                try {
                    for (int i = 0; i < 10; i++) {
                        subscriber.onNext(i);
                        try {
                            Thread.currentThread().sleep(i * 1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    subscriber.onCompleted();
                } catch (Exception e) {
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
                .debounce(5, TimeUnit.SECONDS)
                .subscribe(new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        LogUtils.d("------->call():" + integer);
                    }
                });
複製程式碼

最後輸出結果是:

03-01 10:01:15.040 3591-3736/com.rxandroid.test1 D/----->: ------->call():5
03-01 10:01:20.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():6
03-01 10:01:26.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():7
03-01 10:01:33.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():8
03-01 10:01:41.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():9
複製程式碼

ok,RxJava的過濾操作符就先介紹到這裡,更多精彩內容,歡迎關注我的微信公眾號——Android機動車

這裡寫圖片描述

相關文章