Rxjava温故知新(三)------RxJava操作符之变换型操作符

1.前言

由于Rxjava是一个变种的观察者设计模式,前面也已经说过了,Rxjava的设计是 一个开始节点,一个结束节点。
但是由于Rxjava提供了很多方便的操作符,使得我们的被观察着把数据发送到观察者的途中,我们可以对被观察着进行变形修改。

Rxjava是一个流式的API集合,所以我们可以通过一条线的方式梳理我们的逻辑,有可能会有多次变换操作,最终拿到想要的结果

画个草图

在这里插入图片描述

接下来讲讲常见的变换操作符有哪些。

  • Map
  • flatMap
  • concatMap
  • groupBy
  • buffer

2.变换型操作符

2.1 Map操作符(使用场景-多)

说明

Observable.map() map操作符是一个简单类型的变换操作,把一个类型通过加工成另外一种类型或者是自己想要的值的结果类型 比如 从int通过自己的逻辑操作变身为String类型等

举例

Observable.just("张三")
            .map(new Function<String, Boolean>() {
                @Override
                public Boolean apply(String name) throws Exception {
                    return name.equals("张三");
                }
            }).subscribe(new Observer<Boolean>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(Boolean b) {
            Log.i(TAG, "onNext: " + b);
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    });

在这里 我们在上游发送的是一个String类型的数据,接收的地方是Boolean类型,在中间 我们就通过map操作符,把String对象转换成了我们想要的值发送出去了。 所以我们在下游观察者里面只需要关心最终的结果就行了。不需要关心中途的判断逻辑。这样一套流式的代码写下来也方便阅读

输出结果

 I/MainActivity: onNext: true

2.2 flatMap操作符(使用场景-多)

说明

Observable.flatMap()将一个简单数据类型 变换为一个被观察者类型,

例子

 Observable.just("张三")
            .flatMap(new Function<String, Observable<String>>() {
                @Override
                public Observable<String> apply(String name) throws Exception {
                    return Observable.just("name = " + name);
                }
            }).subscribe(new Observer<String>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(String str) {
            Log.i(TAG, "onNext: " + str);
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    });

输出结果:

I/MainActivity: onNext: name = 张三

2.3 concatMap操作符(使用场景-多)

说明

和flatMap一样的使用,唯一的区别就是发送出来的数据是有序的,就说明如果上游发出的数据是一个集合类型的时候,
如果你又要想保持顺序的输出,那么你就需要选择使用concatMap来实现。(如果市异步操作,可以采用该操作符来实现)

例子

Observable.just("www.baidu.com", "www.sina.com", "www.163.com")
            .concatMap(new Function<String, Observable<String>>() {
                @Override
                public Observable<String> apply(String hostName) throws Exception {
                    return getIPAddress(hostName);
                }
            })
            .subscribe(new Observer<String>() {
                @Override
                public void onSubscribe(Disposable d) {

                }

                @Override
                public void onNext(String str) {
                    Log.i(TAG, " " + str + " , currentThread =  " + Thread.currentThread());
                }

                @Override
                public void onError(Throwable e) {
                    Log.i(TAG, "onError: " + e.getMessage());
                }

                @Override
                public void onComplete() {
                    Log.i(TAG, "onComplete: ");
                }
            });


 private  Observable<String> getIPAddress(final String hostName) {
    return Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            InetAddress ip = null;
            try {
                ip = InetAddress.getByName(hostName);
                String hostAddress = ip.getHostAddress();
                emitter.onNext(hostName + " => " + hostAddress);
				// 如果是concatMap需要调用该方法,否则会阻塞
                emitter.onComplete();
            } catch (UnknownHostException e) {
                e.printStackTrace();
            }
        }
    }).subscribeOn(Schedulers.io());
}

输出结果 (有序的)

I/MainActivity:  www.baidu.com => 180.101.49.11 , currentThread =  Thread[RxCachedThreadScheduler-1,5,main]
I/MainActivity:  www.sina.com => 183.136.135.213 , currentThread =  Thread[RxCachedThreadScheduler-2,5,main]
I/MainActivity:  www.163.com => 183.131.64.220 , currentThread =  Thread[RxCachedThreadScheduler-1,5,main]
I/MainActivity: onComplete: 

对比flatMap的输出结果 这里就贴上面的代码 只不过是把concatMap改为flatMap

 I/MainActivity:  www.163.com => 183.131.64.254 , currentThread =  Thread[RxCachedThreadScheduler-3,5,main]
 I/MainActivity:  www.sina.com => 115.238.192.239 , currentThread =  Thread[RxCachedThreadScheduler-2,5,main]
 I/MainActivity:  www.baidu.com => 180.101.49.11 , currentThread =  Thread[RxCachedThreadScheduler-1,5,main]

上面可以看到concatMap和flatMap的输出结果是不一致的,concatMap的输出结果是一致的,flatMap是无序的。

2.4 groupBy操作符(使用场景-多)

说明

groupBy 根据一定的条件将数据分组,类似于用map保存分组后的数据

例子

 Observable.just(1,2,3,4,5,6)
            .groupBy(new Function<Integer, String>() {
                @Override
                public String apply(Integer integer) throws Exception {
                    return integer>3?"小学":"幼儿园";
                }
            }).subscribe(new Consumer<GroupedObservable<String, Integer>>() {
        @Override
        public void accept(GroupedObservable<String, Integer> stringIntegerGroupedObservable) throws Exception {

            System.out.println("stringIntegerGroupedObservable = [" + stringIntegerGroupedObservable.getKey() + "]");
            stringIntegerGroupedObservable.subscribe(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) throws Exception {
                    System.out.println("stringIntegerGroupedObservable.getKey() [" + integer + "]");
                }
            });
        }
    });

输出结果,按照幼儿园和小学分组分开打印,这里需要注意的是

I/System.out: stringIntegerGroupedObservable = [幼儿园]
I/System.out: stringIntegerGroupedObservable.getKey() [1]
I/System.out: stringIntegerGroupedObservable.getKey() [2]
I/System.out: stringIntegerGroupedObservable.getKey() [3]
I/System.out: stringIntegerGroupedObservable = [小学]
I/System.out: stringIntegerGroupedObservable.getKey() [4]
I/System.out: stringIntegerGroupedObservable.getKey() [5]
I/System.out: stringIntegerGroupedObservable.getKey() [6]

2.5 buffer操作符(使用场景-一般)

说明

buffer(nunmber) 根据number数值分组发射number组的数据, 意味着下游接收的数据是一个list

例子

 Observable.just(1, 2, 3, 4, 5, 6)
            .buffer(2).subscribe(new Observer<List<Integer>>() {
        @Override
        public void onSubscribe(Disposable d) {

        }

        @Override
        public void onNext(List<Integer> integers) {
            Log.i(TAG, "onNext: "+integers);
        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onComplete() {

        }
    });

输出结果,因为这里number是2 所以一组同时发射2条数据,如果最后剩余的数据不满足number,则一次发射完

 I/MainActivity: onNext: [1, 2]
 I/MainActivity: onNext: [3, 4]
 I/MainActivity: onNext: [5, 6]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值