Android RxJava使用介绍(三) RxJava的操作符

Rxjava3 全新详解及常用操作符 RxJava 是一个基于 Java 的响应式编程库,用于处理异步事件流和数据流。它是由 Netflix 开发并开源,现在广泛用于 Android 和 Java 后端开发。RxJava 提供了一种用于组合和处理异步数据的丰富工具集,它的核心思想是将数据流视为一系列事件,以响应事件的方式进行处理。RxJava 提供了丰富的操作符,用于处理和转换数据流。这些操作符可以帮助你执行各种操作,包括过滤、映射、合并、变换等,以便更好地处理异步数据流。 阅读详情

上一篇文章已经详细讲解了RxJava的创建型操作符,本片文章将继续讲解RxJava操作符,包括:

  • Transforming Observables(Observable的转换操作符)
  • Filtering Observables(Observable的过滤操作符)

Transforming Observables(Observable的转换操作符)

buffer操作符

buffer操作符周期性地收集源Observable产生的结果到列表中,并把这个列表提交给订阅者,订阅者处理后,清空buffer列表,同时接收下一次收集的结果并提交给订阅者,周而复始。

需要注意的是,一旦源Observable在产生结果的过程中出现异常,即使buffer已经存在收集到的结果,订阅者也会马上收到这个异常,并结束整个过程。

buffer的名字很怪,但是原理很简单,流程图如下:
这里写图片描述

调用例子如下:

//定义邮件内容
        final String[] mails = new String[]{"Here is an email!", "Another email!", "Yet another email!"};
        //每隔1秒就随机发布一封邮件
        Observable<String> endlessMail = Observable.create(new Observable.OnSubscribe<String>() {
            @Override
            public void call(Subscriber<? super String> subscriber) {
                try {
                    if (subscriber.isUnsubscribed()) return;
                    Random random = new Random();
                    while (true) {
                        String mail = mails[random.nextInt(mails.length)];
                        subscriber.onNext(mail);
                        Thread.sleep(1000);
                    }
                } catch (Exception ex) {
                    subscriber.onError(ex);
                }
            }
        }).subscribeOn(Schedulers.io());
        //把上面产生的邮件内容缓存到列表中,并每隔3秒通知订阅者
        endlessMail.buffer(3, TimeUnit.SECONDS).subscribe(new Action1<List<String>>() {
            @Override
            public void call(List<String> list) {

                System.out.println(String.format("You've got %d new messages!  Here they are!", list.size()));
                for (int i = 0; i < list.size(); i++)
                    System.out.println("**" + list.get(i).toString());
            }
        });

运行结果如下:
You’ve got 3 new messages! Here they are!(after 3s)
**Here is an email!
**Another email!
**Another email!
You’ve got 3 new messages! Here they are!(after 6s)
**Here is an email!
**Another email!
**Here is an email!
……

flatMap操作符

flatMap操作符是把Observable产生的结果转换成多个Observable,然后把这多个Observable“扁平化”成一个Observable,并依次提交产生的结果给订阅者。

flatMap操作符通过传入一个函数作为参数转换源Observable,在这个函数中,你可以自定义转换规则,最后在这个函数中返回一个新的Observable,然后flatMap操作符通过合并这些Observable结果成一个Observable,并依次提交结果给订阅者。

值得注意的是,flatMap操作符在合并Observable结果时,有可能存在交叉的情况,如下流程图所示:
这里写图片描述

调用例子如下:

private Observable<File> listFiles(File f){
        if(f.isDirectory()){
            return Observable.from(f.listFiles()).flatMap(new Func1<File, Observable<File>>() {
                @Override
                public Observable<File> call(File file) {
                    return listFiles(f);
                }
            });
        } else {
            return Observable.just(f);
        }
    }


    @Override
    public void onClick(View v) {
        Observable.just(getApplicationContext().getExternalCacheDir())
                .flatMap(new Func1<File, Observable<File>>() {
                    @Override
                    public Observable<File> call(File file) {
                        //参数file是just操作符产生的结果,这里判断file是不是目录文件,如果是目录文件,则递归查找其子文件flatMap操作符神奇的地方在于,返回的结果还是一个Observable,而这个Observable其实是包含多个文件的Observable的,输出应该是ExternalCacheDir下的所有文件
                        return listFiles(file);
                    }
                })
                .subscribe(new Action1<File>() {
                    @Override
                    public void call(File file) {
                        System.out.println(file.getAbsolutePath());
                    }
                });

    }

concatMap操作符

cancatMap操作符与flatMap操作符类似,都是把Observable产生的结果转换成多个Observable,然后把这多个Observable“扁平化”成一个Observable,并依次提交产生的结果给订阅者。

与flatMap操作符不同的是,concatMap操作符在处理产生的Observable时,采用的是“连接(concat)”的方式,而不是“合并(merge)”的方式,这就能保证产生结果的顺序性,也就是说提交给订阅者的结果是按照顺序提交的,不会存在交叉的情况。

concatMap的流程如下:
这里写图片描述

concatMap的调用例子与flatMap类似,这里不做重复

switchMap操作符

switchMap操作符与flatMap操作符类似,都是把Observable产生的结果转换成多个Observable,然后把这多个Observable“扁平化”成一个Observable,并依次提交产生的结果给订阅者。

与flatMap操作符不同的是,switchMap操作符会保存最新的Observable产生的结果而舍弃旧的结果,举个例子来说,比如源Observable产生A、B、C三个结果,通过switchMap的自定义映射规则,映射后应该会产生A1、A2、B1、B2、C1、C2,但是在产生B2的同时,C1已经产生了,这样最后的结果就变成A1、A2、B1、C1、C2,B2被舍弃掉了!流程图如下:
这里写图片描述

以下是flatMap、concatMap和switchMap的运行实例对比:


        //flatMap操作符的运行结果
        Observable.just(10, 20, 30).flatMap(new Func1<Integer, Observable<Integer>>() {
            @Override
            public Observable<Integer> call(Integer integer) {
                //10的延迟执行时间为200毫秒、20和30的延迟执行时间为180毫秒
                int delay = 200;
                if (integer > 10)
                    delay = 180;

                return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("flatMap Next:" + integer);
            }
        });

        //concatMap操作符的运行结果
        Observable.just(10, 20, 30).concatMap(new Func1<Integer, Observable<Integer>>() {
            @Override
            public Observable<Integer> call(Integer integer) {
                //10的延迟执行时间为200毫秒、20和30的延迟执行时间为180毫秒
                int delay = 200;
                if (integer > 10)
                    delay = 180;

                return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("concatMap Next:" + integer);
            }
        });

        //switchMap操作符的运行结果
        Observable.just(10, 20, 30).switchMap(new Func1<Integer, Observable<Integer>>() {
            @Override
            public Observable<Integer> call(Integer integer) {
                //10的延迟执行时间为200毫秒、20和30的延迟执行时间为180毫秒
                int delay = 200;
                if (integer > 10)
                    delay = 180;

                return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("switchMap Next:" + integer);
            }
        });

运行结果如下:
flatMap Next:20
flatMap Next:10
flatMap Next:30
flatMap Next:15
flatMap Next:10
flatMap Next:5

switchMap Next:30
switchMap Next:15

concatMap Next:10
concatMap Next:5
concatMap Next:20
concatMap Next:10
concatMap Next:30
concatMap Next:15

groupBy操作符

groupBy操作符是对源Observable产生的结果进行分组,形成一个类型为GroupedObservable的结果集,GroupedObservable中存在一个方法为getKey(),可以通过该方法获取结果集的Key值(类似于HashMap的key)。

值得注意的是,由于结果集中的GroupedObservable是把分组结果缓存起来,如果对每一个GroupedObservable不进行处理(既不订阅执行也不对其进行别的操作符运算),就有可能出现内存泄露。因此,如果你对某个GroupedObservable不进行处理,最好是对其使用操作符take(0)处理。

groupBy操作符的流程图如下:
这里写图片描述

调用例子如下:

Observable.interval(1, TimeUnit.SECONDS).take(10).groupBy(new Func1<Long, Long>() {
            @Override
            public Long call(Long value) {
                //按照key为0,1,2分为3组
                return value % 3;
            }
        }).subscribe(new Action1<GroupedObservable<Long, Long>>() {
            @Override
            public void call(GroupedObservable<Long, Long> result) {
                result.subscribe(new Action1<Long>() {
                    @Override
                    public void call(Long value) {
                        System.out.println("key:" + result.getKey() +", value:" + value);
                    }
                });
            }
        });

运行结果如下:
key:0, value:0
key:1, value:1
key:2, value:2
key:0, value:3
key:1, value:4
key:2, value:5
key:0, value:6
key:1, value:7
key:2, value:8
key:0, value:9

map操作符

map操作符是把源Observable产生的结果,通过映射规则转换成另一个结果集,并提交给订阅者进行处理。

map操作符的流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1,2,3,4,5,6).map(new Func1<Integer, Integer>() {
            @Override
            public Integer call(Integer integer) {
                //对源Observable产生的结果,都统一乘以3处理
                return integer*3;
            }
        }).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("next:" + integer);
            }
        });

运行结果如下:
next:3
next:6
next:9
next:12
next:15
next:18

cast操作符

cast操作符类似于map操作符,不同的地方在于map操作符可以通过自定义规则,把一个值A1变成另一个值A2,A1和A2的类型可以一样也可以不一样;而cast操作符主要是做类型转换的,传入参数为类型class,如果源Observable产生的结果不能转成指定的class,则会抛出ClassCastException运行时异常。

cast操作符的流程图如下:
这里写图片描述

调用例子如下:

        Observable.just(1,2,3,4,5,6).cast(Integer.class).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer value) {
                System.out.println("next:"+value);
            }
        });

运行结果如下:
next:1
next:2
next:3
next:4
next:5
next:6

scan操作符

scan操作符通过遍历源Observable产生的结果,依次对每一个结果项按照指定规则进行运算,计算后的结果作为下一个迭代项参数,每一次迭代项都会把计算结果输出给订阅者。

scan操作符的流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1, 2, 3, 4, 5)
    .scan(new Func2<Integer, Integer, Integer>() {
        @Override
        public Integer call(Integer sum, Integer item) {
            //参数sum就是上一次的计算结果
            return sum + item;
        }
    }).subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });

运行结果如下:
Next: 1
Next: 3
Next: 6
Next: 10
Next: 15
Sequence complete.

window操作符

window操作符非常类似于buffer操作符,区别在于buffer操作符产生的结果是一个List缓存,而window操作符产生的结果是一个Observable,订阅者可以对这个结果Observable重新进行订阅处理。

window操作符有很多个重载方法,这里只举一个简单的例子,其流程图如下:
这里写图片描述

调用例子如下:

Observable.interval(1, TimeUnit.SECONDS).take(12)
                .window(3, TimeUnit.SECONDS)
                .subscribe(new Action1<Observable<Long>>() {
                    @Override
                    public void call(Observable<Long> observable) {
                        System.out.println("subdivide begin......");
                        observable.subscribe(new Action1<Long>() {
                            @Override
                            public void call(Long aLong) {
                                System.out.println("Next:" + aLong);
                            }
                        });
                    }
                });

运行结果如下:
subdivide begin……
Next:0
Next:1
subdivide begin……
Next:2
Next:3
Next:4
subdivide begin……
Next:5
Next:6
Next:7
subdivide begin……
Next:8
Next:9
Next:10
subdivide begin……
Next:11

Filtering Observables(Observable的过滤操作符)

debounce操作符

debounce操作符对源Observable每产生一个结果后,如果在规定的间隔时间内没有别的结果产生,则把这个结果提交给订阅者处理,否则忽略该结果。

值得注意的是,如果源Observable产生的最后一个结果后在规定的时间间隔内调用了onCompleted,那么通过debounce操作符也会把这个结果提交给订阅者。

debounce操作符的流程图如下:
这里写图片描述

调用例子如下:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    //产生结果的间隔时间分别为100、200、300...900毫秒
                    for (int i = 1; i < 10; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(i * 100);
                    }
                    subscriber.onCompleted();
                }catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
          .debounce(400, TimeUnit.MILLISECONDS)  //超时时间为400毫秒
          .subscribe(
                new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        System.out.println("Next:" + integer);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        System.out.println("Error:" + throwable.getMessage());
                    }
                }, new Action0() {
                    @Override
                    public void call() {
                        System.out.println("completed!");
                    }
                });

运行结果如下:
Next:4
Next:5
Next:6
Next:7
Next:8
Next:9
completed!

distinct操作符

distinct操作符对源Observable产生的结果进行过滤,把重复的结果过滤掉,只输出不重复的结果给订阅者,非常类似于SQL里的distinct关键字。

distinct操作符的流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1, 2, 1, 1, 2, 3)
          .distinct()
          .subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });

运行结果如下:
Next: 1
Next: 2
Next: 3
Sequence complete.

elementAt操作符

elementAt操作符在源Observable产生的结果中,仅仅把指定索引的结果提交给订阅者,索引是从0开始的。其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1,2,3,4,5,6).elementAt(2)
          .subscribe(
                new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        System.out.println("Next:" + integer);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        System.out.println("Error:" + throwable.getMessage());
                    }
                }, new Action0() {
                    @Override
                    public void call() {
                        System.out.println("completed!");
                    }
                });

运行结果如下:
Next:3
completed!

filter操作符

filter操作符是对源Observable产生的结果按照指定条件进行过滤,只有满足条件的结果才会提交给订阅者,其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1, 2, 3, 4, 5)
          .filter(new Func1<Integer, Boolean>() {
              @Override
              public Boolean call(Integer item) {
                return( item < 4 );
              }
          }).subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });

运行结果如下:
Next: 1
Next: 2
Next: 3
Sequence complete.

ofType操作符

ofType操作符类似于filter操作符,区别在于ofType操作符是按照类型对结果进行过滤,其流程图如下:
这里写图片描述
调用例子如下:

Observable.just(1, "hello world", true, 200L, 0.23f)
          .ofType(Float.class)
          .subscribe(new Subscriber<Object>() {
              @Override
              public void onNext(Object item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 0.23
Sequence complete.

first操作符

first操作符是把源Observable产生的结果的第一个提交给订阅者,first操作符可以使用elementAt(0)和take(1)替代。其流程图如下:
这里写图片描述
调用例子如下:

        Observable.just(1,2,3,4,5,6,7,8)
          .first()
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 1
Sequence complete.

single操作符

single操作符是对源Observable的结果进行判断,如果产生的结果满足指定条件的数量不为1,则抛出异常,否则把满足条件的结果提交给订阅者,其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1,2,3,4,5,6,7,8)
          .single(new Func1<Integer, Boolean>() {
              @Override
              public Boolean call(Integer integer) {
                  //取大于10的第一个数字
                  return integer>10;
              }
          })
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Error: Sequence contains no elements

last操作符

last操作符把源Observable产生的结果的最后一个提交给订阅者,last操作符可以使用takeLast(1)替代。其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1, 2, 3)
          .last()
          .subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });

运行结果如下:
Next: 3
Sequence complete.

ignoreElements操作符

ignoreElements操作符忽略所有源Observable产生的结果,只把Observable的onCompleted和onError事件通知给订阅者。ignoreElements操作符适用于不太关心Observable产生的结果,只是在Observable结束时(onCompleted)或者出现错误时能够收到通知。

ignoreElements操作符的流程图如下:
这里写图片描述

调用例子如下:

        Observable.just(1,2,3,4,5,6,7,8).ignoreElements()
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Sequence complete.

sample操作符

sample操作符定期扫描源Observable产生的结果,在指定的时间间隔范围内对源Observable产生的结果进行采样,其流程图如下:
这里写图片描述

调用例子如下:

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    //前8个数字产生的时间间隔为1秒,后一个间隔为3秒
                    for (int i = 1; i < 9; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(1000);
                    }
                    Thread.sleep(2000);
                    subscriber.onNext(9);
                    subscriber.onCompleted();
                } catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
          .sample(2200, TimeUnit.MILLISECONDS)  //采样间隔时间为2200毫秒
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 3
Next: 5
Next: 7
Next: 8
Sequence complete.

skip操作符

skip操作符针对源Observable产生的结果,跳过前面n个不进行处理,而把后面的结果提交给订阅者处理,其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1,2,3,4,5,6,7).skip(3)
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 4
Next: 5
Next: 6
Next: 7
Sequence complete.

skipLast操作符

skipLast操作符针对源Observable产生的结果,忽略Observable最后产生的n个结果,而把前面产生的结果提交给订阅者处理,

值得注意的是,skipLast操作符提交满足条件的结果给订阅者是存在延迟效果的,看以下流程图即可明白:
这里写图片描述

可以看到skipLast操作符把最后的天蓝色球、蓝色球、紫色球忽略掉了,但是前面的红色球等并不是源Observable一产生就直接提交给订阅者,这里有一个延迟的效果。

调用例子如下:

Observable.just(1,2,3,4,5,6,7).skipLast(3)
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 1
Next: 2
Next: 3
Next: 4
Sequence complete.

take操作符

take操作符是把源Observable产生的结果,提取前面的n个提交给订阅者,而忽略后面的结果,其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1, 2, 3, 4, 5, 6, 7, 8)
          .take(4)
          .subscribe(new Subscriber<Integer>() {
        @Override
        public void onNext(Integer item) {
            System.out.println("Next: " + item);
        }

        @Override
        public void onError(Throwable error) {
            System.err.println("Error: " + error.getMessage());
        }

        @Override
        public void onCompleted() {
            System.out.println("Sequence complete.");
        }
    });

运行结果如下:
Next: 1
Next: 2
Next: 3
Next: 4
Sequence complete.

takeFirst操作符

takeFirst操作符类似于take操作符,同时也类似于first操作符,都是获取源Observable产生的结果列表中符合指定条件的前一个或多个,与first操作符不同的是,first操作符如果获取不到数据,则会抛出NoSuchElementException异常,而takeFirst则会返回一个空的Observable,该Observable只有onCompleted通知而没有onNext通知。

takeFirst操作符的流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1,2,3,4,5,6,7).takeFirst(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                //获取数值大于3的数据
                return integer>3;
            }
        })
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 4
Sequence complete.

takeLast操作符

takeLast操作符是把源Observable产生的结果的后n项提交给订阅者,提交时机是Observable发布onCompleted通知之时。其流程图如下:
这里写图片描述

调用例子如下:

Observable.just(1,2,3,4,5,6,7).takeLast(2)
          .subscribe(new Subscriber<Integer>() {
              @Override
              public void onNext(Integer item) {
                  System.out.println("Next: " + item);
              }

              @Override
              public void onError(Throwable error) {
                  System.err.println("Error: " + error.getMessage());
              }

              @Override
              public void onCompleted() {
                  System.out.println("Sequence complete.");
              }
          });

运行结果如下:
Next: 6
Next: 7
Sequence complete.

不知不觉介绍了那么多操作符,篇幅有点长了,下回继续介绍其他的操作符,敬请期待!

RXJava学习(一Observable) RxJava几个概念:Observable被观察者,Observer观察者;subscribe建立两者的关系,如下:observable.subscribe(observer);RxJava使用由来:RX是微软.net的一个响应式扩展,rx借助可观测的序列提供一种简单的方式来创建异步的,基于事件驱动的程序。2012年Netflix为了应对不断增长的业务需求开始将.NET Rx迁移到JVM上面。并于... 阅读详情

相关推荐

RxJava操作符入门

【代码】RxJava操作符入门。

肇秋贰拾捌的博客 1304

RxJava操作符

文章目录RxJava创建型操作符create()操作符just()操作符fromArray()操作符fromIterable()操作符differ()操作符timer()操作符interval()操作符intervalRange()操作符range()操作符rangeLong()操作符其他RxJava变换操作符map()操作符flatMap()操作符concatMap()操作符buffer()操作...

川峰的博客 4744

RxJava操作符汇总

RxJava操作符包含的操作符类型有如下几种: 1、创建操作符 :创建被观察者(Observable)对象&发送事件 转自:RxJava操作符汇总_zengke的博客-CSDN博客_rxjava操作符 https://blog.csdn.net/zengke1993/article/details/80388510 ...

chuyouyinghe的专栏 6088

Android RxJava使用介绍(二) RxJava操作符

上一篇文章我们通过一个简单的例子来给大家展示了RxJava的基本用法,相信大家已经对RxJava有了大概的了解,由于上篇文章对RxJava使用介绍都是点到为止,并没有进行深入展开,也许你对RxJava有种名不副实的感觉。OK,下面我们就进入正题,一步步的揭开RxJava的神秘面纱!一个例子RxJava的强大之处,在于它提供了非常丰富且功能强悍的操作符,通过使用和组合这些操作符,你几乎能完成所有你想

呼啸而过的专栏 3万+

Android RxJava使用介绍(四) RxJava操作符

本篇文章继续介绍以下类型的操作符 Combining Observables(Observable的组合操作符) Error Handling Operators(Observable的错误处理操作符) Combining Observables(Observable的组合操作符)combineLatest操作符combineLatest操作符把两个Observable产生的结果进行合并,合并的结果

呼啸而过的专栏 1万+

Android-Rxjava 常用操作符

Rxjava的优势 提高工作效率 能优雅的解决复杂的业务场景 1.Rxjava原理 RxJava 的原理就是创建一个 Observable 对象来干活,然后使用各种操作符建立起来的链式操作,就如同流水线一样,把你想要处理的数据一步一步地加工成你想要的成品,然后发射给 Subscriber 处理。 2.使用Rxjava需要添加的依赖 implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.

风的轨迹 4982

Android RxJava: 这是一份全面的 操作符 使用汇总 (含详细实例讲解)

RxJava作为一名从事Android的开发者,很多人最近都在和我吐槽Android是不是快要凉了?而在我看来这正是市场成熟的表现,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!,所有的市场都是温水煮青蛙,永远会淘汰掉不愿意学习改变,安于现状的那批人,希望所有的人能在大浪淘沙中留下来,因为对于市场的逐渐成熟,平凡并不是我们唯一的答案!

2401_86022628的博客 1798

Android框架——RxJava)转换操作符

RxJava1.x(二)操作符详解 上一篇博客已经讲解了RxJava的API的基本使用,这里我们来学习下RxJava的另一个特性——对数据流的转换操作符RxJava中提供的操作符可以分为转换类操作符,过滤类操作符以及组合类操作符,接下来我将依次对这操作符使用进行讲解。 一、转换类操作符 转换类操作符顾名思义,就是将上游(被观察者)发送的数据流进行转换成另外一种形式(观察者希...

boyeleven的博客 2258

AndroidRxjava2.X 2————Rxjava 创建操作符

AndroidRxjava2.X 2————Rxjava 创建操作符 一.目录 AndroidRxjava2.X 2————Rxjava 创建操作符 一.目录 二.概述 1.作用 2. 类型 .基本创建 1. create() 四.快速创建 1.just() 2.fromArray() 3.fromIterable() 4.其他 五. 延迟创建 1.defer() ...

冰炭不投day的博客 1952

RxJava基础操作符和高级操作符

每个操作符(如 map, filter)内部通常会调用 lift(Operator) 方法,创建一个新的 Observable,这个新的 Observable 会包装上游的 Observable,并在订阅时,将下游的 Observer 包装成一个新的 Observer,从而在数据传递过程中插入转换或过滤逻辑。extends R>>): 将每个发射的项转换成一个新的 Observable,然后将这些 Observable 发射的数据“拍平”并合并到一个单一的 Observable 中。

csdn_silent的博客 1349

Android RxJava操作符

最近参照文档对RxJava一系列操作符作了一下理解。 一、创建类操作符 1、Create 创建一个Observable,返回一个emitter(发射器),手动调用onNext(),onError(),onComplete()方法。 2、from Array,Just 创建一个将要发出的一个或一组对象的Observable,会自行调用onNext(),onComplete方法。Just...

weixin_40929353的博客 499

安卓进阶——RxJava

RxJava是由Netflix开发的响应式编程框架,基于观察者模式简化异步编程。核心组件包括Observable(数据发射源)、Observer(数据处理者)、Subject(双向桥梁)和Subscription(订阅管理)。框架提供创建、转换、过滤、组合等丰富操作符,支持线程调度控制(如subscribeOn/observeOn)。典型应用场景包括网络请求链式调用、UI事件防抖、生命周期管理等。需注意内存泄漏防护(CompositeDisposable)、合理选择操作符及错误处理机制。其流式...

Meteors.的博客 1194
上一篇: Android RxJava使用介绍(二) RxJava的操作符
下一篇: Android RxJava使用介绍(四) RxJava的操作符
呼啸而过11
博客等级 码龄19年 120粉丝 13原创
评论 11
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值