Rxjava过滤操作符

Rxjava操作符索引

 这篇章主要介绍Rxjava的变换操作符

目录

Debounce

Distinct

distinct

distinctUntilChanged

distinct(Func1)

ElementAt

Filter

filter

ofType

First

IgnoreElements

Last

Skip

Take


Debounce

仅在过了一段指定的时间还没发射数据时才发射一个数据,Debounce操作符会过滤掉发射速率过快的数据项。其实我也没理解它说啥。看下面代码:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
                observableEmitter.onNext(1);
                Thread.sleep(200);
                observableEmitter.onNext(2);
                Thread.sleep(300);
                observableEmitter.onNext(3);
                Thread.sleep(302);
                observableEmitter.onNext(4);
                Thread.sleep(100);
                observableEmitter.onNext(5);
                Thread.sleep(420);
                observableEmitter.onNext(6);//
            }
        }).debounce(300, TimeUnit.MILLISECONDS) // ThrottleWithTimeout与其功能一样
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        System.out.println(s + "*");
                    }
                });

结果:

3*
5*

就只有3和5发送后,后面睡眠时间超过300毫秒,所以就只有他们打印出来。

Distinct

distinct

过滤掉重复的数据项,这个是过滤全列表重复,为什么提醒是全列表呢,后面还有一个类似的操作符,先看这个的代码。

Observable.just(1, 2, 1, 1, 2, 3)
                .distinct()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        System.out.println(s + "*");
                    }
                });

结果:

1*
2*
3*

distinctUntilChanged

这个跟上面的区别就是过滤连续的重复,只要看代码结果就明白了

Observable.just(1, 2, 1, 1, 2, 3)
                .distinctUntilChanged()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        System.out.println(s + "*");
                    }
                });

结果:

1*
2*
1*
2*
3*

这操作符只会去掉连续重复的1,只让连续的1里面保留一个1。

distinct(Func1)

distinctUntilChanged也有类似的做法,里面放一个函数。主要是数据源是基本类型的时候,distinct可以帮我们自动进行过滤操作。但数据源不是基本类型,或者你想修改过滤规则,就可以填入自己写的Func1函数。函数要返回一个用于比较的基本类型。

Student[] students = {new Student("1"), new Student("2"), new Student("1"),new Student("1"), new Student("2"),new Student("3")};
        Observable.fromArray(students)
                .distinct(student -> student.getName())
                .subscribe(student -> System.out.println(student.getName() + "*"));

结果:

1*
2*
3*

ElementAt

只发射第N项数据,代码如下:

Observable.just(1, 2, 3, 4, 5, 6)
                .elementAt(3)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        System.out.println(s + "*");
                    }
                });

结果:

4*

结果一看就明白,不用我多说。elementAt越界会怎样。

Observable.just(1, 2, 3, 4, 5, 6)
                .elementAt(8)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        System.out.println(s + "*");
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable throwable) throws Throwable {
                        System.out.println(throwable.getMessage() + "+");
                    }
                });

上面的代码是没输出结果的,elementAt里面传8,已经超过我们的数据源的size,但也不会进异常。把elementAt改成elementAtOrError操作符,就会进入异常了。

elementAt还可以传入默认值,当越界的时候就会输出默认值,代码如下:

Observable.just(1, 2, 3, 4, 5, 6)
                .elementAt(8,0)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        System.out.println(s + "*");
                    }
                });

结果:

0*

Filter

filter

简单一句,就写一个条件,符合你写的过滤条件,才会被输出

Observable.just(1, 2, 3, 4, 5, 6)
                .filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) throws Throwable {
                        return integer <= 4;
                    }
                })
                .subscribe(integer -> System.out.println(integer+"*"));

结果:

1*
2*
3*
4*

ofType

ofTypefilter操作符的一个特殊形式。它过滤一个Observable只返回指定类型的数据。总之就是过滤你数据源指定的类型,才能被输出

Person[] peoples = {new Student("aaa"), new Teacher("bbb"), new Student("ccc")};
        Observable.fromArray(peoples)
                .ofType(Student.class)
                .subscribe(people -> System.out.println(((Student)people).getName()));

结果:

aaa
ccc

上面Student和Teacher类都继承Person类,然后结果只会输出Student类的名字

First

Observable.just(1,2,3)
                .firstElement()
                .subscribe(integer -> System.out.println(integer+"*"));

结果:

1*

其实firstElement效果就是上面elementAt(0),输出数据源第一个数据。但也会用越界的情况,比如数据源是空的,所有有个firstOrError跟elementAtOrError对应。也可以像elementAt填入默认值,如下:

Observable.empty()
                .first(2)
                .subscribe(integer -> System.out.println(integer+"*"));

结果:

2*

因为数据源为空,结果就会输出默认值2

IgnoreElements

简单一说,就是这个操作符会忽略所有onNext的操作,直接进onError或onComplete

Observable.create(new ObservableOnSubscribe<String>() {
            @Override
            public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
                observableEmitter.onNext("1");
                observableEmitter.onComplete();
            }
        }).ignoreElements().subscribe(new Action() {
            @Override
            public void run() throws Throwable {
                System.out.println("完成");
            }
        }, new Consumer<Throwable>() {
            @Override
            public void accept(Throwable throwable) throws Throwable {
                System.out.println("异常");
            }
        });

结果:

完成

不过onNext传递什么数据,它也只会进onComplete。大家可能会说,你都不写onNext的action给它订阅当然不进onNext。不是我不想写,是你用了ignoreElements后,后面的订阅就只能是onComplete和onError

Last

Observable.just(1,2,3)
                .lastElement()
                .subscribe(integer -> System.out.println(integer+"*"));

结果:

3*

这个真的不多说了,就是跟first操作符相反,输出最后一个数据源,当然异常和默认值写法也一样。

Skip

跳过指定个数的数据源,输出之后剩下的数据

Observable.just(1,2,3,4,5,6)
                .skip(3)
                .subscribe(integer -> System.out.println(integer+"*"));

        Observable.just(1,2,3,4,5,6)
                .skipLast(3)
                .subscribe(integer -> System.out.println(integer+"*"));

结果:

4*
5*
6*
1*
2*
3*

第一段代码输出4,5,6因为前面跳过了3个,而skipLast也好理解,就是从后面跳三个,所以结果是1,2,3。

skip和skipLast除了跳过个数,还可以跳过时间,如skip(3,TimeUnit.SECONDS),就是跳过前面3秒内的数据源,输出3秒后的数据。

Take

只发射前面N条数据,其实就是跟skip相反,skip跳过的那些就是take想发送的那些

Observable.just(1,2,3,4,5,6)
                .take(3)
                .subscribe(integer -> System.out.println(integer+"*"));

结果:

1*
2*
3*

看结果和结合我的描述,相信已经明白。当然对应的take也有takeLast操作符,也可以跳过时间。

发布了17 篇原创文章 · 获赞 11 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/DNWalter/article/details/102646604
今日推荐