Android响应式编程——RxJava3框架的使用(二)

本文深入介绍了RxJava3框架的常用操作符,包括创建、转换、过滤、组合、错误处理、辅助性、条件和布尔、数学运算及聚合、连接等操作符的用法和示例,帮助开发者更好地理解和运用RxJava进行Android响应式编程。
摘要由CSDN通过智能技术生成

文章导航

Android响应式编程——RxJava3框架的使用(一)

Android响应式编程——RxJava3框架的使用(二)

Android响应式编程——RxJava3框架的使用(三)

Android响应式编程——RxJava3框架的使用(四)

RxJava常用操作符

1.创建操作符

  1. create():创建最简单的事件流
  2. from():创建事件流,可发送不同类型的数据流
  3. just():创建事件流,可发送多个参数的数据流
  4. defer():创建事件流,可缓存可激活事件流
  5. range():创建事件流,可发送范围内的数据流
  6. interval():创建延时重复的事件流
  7. repeat():创建可重复次数的事件流
  8. timer():创建一次延时的事件流

补充:interval()、timer()、delay()的区别

  • interval():用于创建事件流,周期性重复发送
  • timer():用于创建事件流,延时发送一次
  • delay():用于事件流中,可以延时某次事件流的发送

1.1 create

create在之前的文章中就有使用,最原生的创建Observable的方式,onNext/onComplete/onError可完全自由控制。
在这里插入图片描述
Observable最原始的创建方式,创建出一个最简单的事件流,可以使用发射器发射特定的数据类型

public static void main(String[] args) {
   
    Observable
            .create(new ObservableOnSubscribe<Integer>() {
   
                @Override
                public void subscribe(@NonNull ObservableEmitter<Integer> e) throws Exception {
   
                    for (int i = 1; i < 5; i++) {
   
                        e.onNext(i);
                    }
                    e.onComplete();
                }
            })
            .subscribe(new Consumer<Integer>() {
   
                @Override
                public void accept(Integer integer) throws Exception {
   
                    System.out.println("onNext=" + integer);
                }
            }, new Consumer<Throwable>() {
   
                @Override
                public void accept(Throwable throwable) throws Exception {
   

                }
            }, new Action() {
   
                @Override
                public void run() throws Exception {
   
                    System.out.println("onComplete");
                }
            });
}

1.2 from

在这里插入图片描述fromArray方法参数为可变长参数,因此既可传数组,也可传多个参数

        String[] strings = {
   "a", "b", "c"};
        Observable.fromArray(strings);
        Observable.fromArray("a", "b", "c");
        Observable.fromArray(1, 2, 3, 4);

fromIterable方法参数为实现Iterable接口的类,一般为JDK中的List/Map/Set等集合类

        String[] strings = {
   "aa12", "bb34", "cc56"};
        List<String> listString = Arrays.asList(strings);
        Observable.fromIterable(listString);

1.3 just

在这里插入图片描述
just重载了多个参数数量不同的方法,最大可带10个参数,just同样是调用的fromArray方法;

public static void main(String[] args) {
   
    Observable.just(1, 2, 3, 4, 5)
            .subscribe(new Consumer<Integer>() {
   
                @Override
                public void accept(Integer integer) throws Exception {
   
                    System.out.println("onNext=" + integer);
                }
            });
}

1.4 defer

在这里插入图片描述defer与just的区别是,just是直接将发射当前的数据流,而defer会等到订阅的时候,才会去执行它的call()回调,再去发射当前的数据流。复杂点的理解就是:defer操作符是将一组数据流在原有的事件流基础上缓存一个新的事件流,直到有人订阅的时候,才会创建它缓存的事件流

    i = 10;
    Observable<Object> defer = Observable.defer(new Callable<ObservableSource<?>>() {
   
        @Override
        public ObservableSource<?> call() throws Exception {
   
            //缓存新的事件流
            return Observable.just(i);
        }
    });

    defer.subscribe(new Consumer<Object>() {
   
        @Override
        public void accept(Object o) throws Exception {
   
            System.out.println("onNext=" + (int) o);
        }
    });
    
	//修改发射的数据
    i = 20;

    defer.subscribe(new Consumer<Object>() {
   
        @Override
        public void accept(Object o) throws Exception {
   
            System.out.println("onNext=" + (int) o);
        }
    });

输出

onNext=10
onNext=20

1.5 range

在这里插入图片描述range操作符发射一个范围内的有序整数数据流,你可以指定范围的起始和长度

public static void main(String[] args) {
   
    Observable.range(10, 4)
            .subscribe(new Consumer<Integer>() {
   
                @Override
                public void accept(Integer integer) throws Exception {
   
                    System.out.println("onNext=" + integer);
                }
            });
}

		//发送从10开始的整数,发送4个(发到13)
        Observable.range(10, 4);
        //发送从10开始的长整型数,发送6个(发到15)
        Observable.rangeLong(10, 6);

1.6 interval

在这里插入图片描述interval用于定时发送

		//每3秒发个自增整数
        Observable.interval(3, TimeUnit.SECONDS);
        //初始延时1秒,每3秒发一个自增整数
        Observable.interval(1, 3, TimeUnit.SECONDS);
		//初始延时2秒,后每1秒发一个从10开始的整数,发5个(发到14)停止
        Observable.intervalRange(10, 5, 2, 1, TimeUnit.SECONDS);

1.7 repeat

在这里插入图片描述repeat操作符可以重复发送指定次数的某个事件流,repeat操作符默认在trampoline调度器上执行,repeat默认重复次数为Long.MAX_VALUE,可使用重载方法指定次数以及使用repeatUntil指定条件

		//一直重复
        Observable.fromArray(1, 2, 3, 4).repeat();
        //重复发送5次
        Observable.fromArray(1, 2, 3, 4).repeat(5);
        //重复发送直到符合条件时停止重复
        Observable.fromArray(1, 2, 3, 4).repeatUntil(new BooleanSupplier() {
   
			@Override
			public boolean getAsBoolean() throws Exception {
   
				//自定判断条件,为true即可停止,默认为false
				return false;
			}
		});

1.8 timer

在这里插入图片描述
timer用于延时发送

		//延时3秒后,发送一个整数0
        Observable.timer(3, TimeUnit.SECONDS);

2.转换操作符

  1. map():对数据流的类型进行转换
  2. flatMap():对数据流的类型进行包装成另一个数据流
  3. scan():对上一轮处理过后的数据流进行函数处理
  4. groupBy():对所有的数据流进行分组
  5. buffer():缓存发射的数据流到一定数量,随后发射出数据流集合
  6. window():缓存发射的数据流到一定数量,随后发射出新的事件流

2.1 map

在这里插入图片描述map利用Function将T转为R

        Observable.just("1", "2", "3").map(new Function<String, Integer>() {
   
			@Override
			public Integer apply(String s) throws Exception {
   
				return Integer.valueOf(s) * 10;
			}
		}).subscribe(new Consumer<Integer>() {
   
			@Override
			public void accept(Integer integer) throws Exception {
   
                System.out.println(integer);
			}
		});

2.2 flatMap/concatMap

在这里插入图片描述
flatMap操作符将数据流进行类型转换,然后将新的数据流传递给新的事件流进行分发,这里通过模拟请求登录的延时操作进行说明

public void flatMap() {
   
    Observable.just(new UserParams("hensen", "123456")).flatMap(new Function<UserParams, ObservableSource<String>>() {
   
        @Override
        public ObservableSource<String> apply(UserParams userParams) throws Exception {
   
            return Observable.just(userParams.username + "登录成功").delay(2, TimeUnit.SECONDS);
        }
    }).subscribe(new Consumer<String>() {
   
        @Override
        public void accept(String s) throws Exception {
   
            System.out.println(s);
        }
    });
}

public static class UserParams {
   

    public UserParams(String username, String password) {
   
        this.username = username;
        this.password = password;
    }

    public String username;
    public String password;
}

输出

hensen登录成功

concatMap与flatMap的区别

  • concatMap是有序的

  • flatMap是乱序的

    2.3 scan

    在这里插入图片描述scan操作符会对发射的数据和上一轮发射的数据进行函数处理,并返回的数据供下一轮使用,持续这个过程来产生剩余的数据流。其应用场景有简单的累加计算,判断所有数据的最小值等

public static void main(String[] args) {
   
    Observable.just(8, 2, 13, 1, 15).scan(new BiFunction<Integer, Integer, Integer>() {
   
        @Override
        public Integer apply(Integer integer, Integer integer2) throws Exception {
   
            return integer < integer2 ? integer : integer2;
        }
    })
            .subscribe(new Consumer<Integer>() {
   
                @Override
                public void accept(Integer item) throws Exception {
   
                    System.out.println("onNext=" + item);
                }
            });
}

输出

onNext=8
onNext=2
onNext=2
onNext=1
onNext=1

2.4 groupBy

在这里插入图片描述groupBy操作符可以将发射出来的数据项进行分组,并将分组后的数据项保存在具有key-value映射的事件流中。groupBy具体的分组规则由groupBy操作符传递进来的函数参数Function所决定的,它可以将key和value按照Function的返回值进行分组,返回一个具有分组规则的事件流GroupedObservable,注意这里分组出来的事件流是按照原始事件流的顺序输出的,我们可以通过sorted()对数据项进行排序,然后输出有序的数据流。

public static void main(String[] args) {
   
    Observable.just("java", "c++", "c", "c#", "javaScript", "Android")
            .groupBy(new Function<String, Character>() {
   
                @Override
                public Character apply(String s) throws Exception {
   
                    return s.charAt(0);//按首字母分组
                }
            })
            .subscribe(new Consumer<GroupedObservable<Character, String>>() {
   
                @Override
                public void accept(final GroupedObservable<Character, String> characterStringGroupedObservable) throws Exception {
   
                    //排序后,直接订阅输出key和value
                    characterStringGroupedObservable.sorted().subscribe(new Consumer<String>() {
   
                        @Override
                        public void accept(String s) throws Exception {
   
                            System.out.println("onNext= key:" + characterStringGroupedObservable.getKey() + " value:" + s);
                        }
                    });
                }
            });
}

输出

onNext= key:A value:Android
onNext= key:c value:c
onNext= key:c value:c#
onNext= key:c value:c++
onNext= key:j value:java
onNext= key:j value:javaScript

2.5 buffer

在这里插入图片描述buffer操作符可以将发射出来的数据流,在给定的缓存池中进行缓存,当缓存池中的数据项溢满时,则将缓存池的数据项进行输出,重复上述过程,直到将发射出来的数据全部发射出去。如果发射出来的数据不够缓存池的大小,则按照当前发射出来的数量进行输出。如果对buffer操作符设置了skip参数,则buffer每次缓存池溢满时,会跳过指定的skip数据项,然后再进行缓存和输出。

Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9)
        .buffer(5).subscribe(new Consumer<List<Integer>>() {
   
    @Override
    public void accept(List<Integer> integers) throws Exception {
   
        System.out.println("onNext=" + integers.toString());
    }
});

输出

onNext=[1, 2, 3, 4, 5]
onNext=[6, 7, 8, 9]

2.6 window

在这里插入图片描述window操作符和buffer操作符在功能上实现的效果是一样的,但window操作符最大区别在于同样是缓存一定数量的数据项,window操作符最终发射出来的是新的事件流integerObservable,而buffer操作符发射出来的是新的数据流,也就是说,window操作符发射出来新的事件流中的数据项,还可以经过Rxjava其他操作符进行处理。

public static void main(String[] args) {
   
    Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9)
            .window(2, 1).subscribe(new Consumer<Observable<Integer>>() {
   
        @Override
        public void accept(Observable<Integer> integerObservable) throws Exception {
   
            integerObservable.subscribe(new Consumer<Integer>() {
   
                @Override
                public void accept(Integer integer) throws Exception {
   
                    System.out.println("onNext=" + integer);
                }
            });
        }
    });
}

输出

onNext=1
onNext=2
onNext=2
onNext=3
onNext=3
onNext=4
onNext=4
onNext=5
onNext=5
onNext=6
onNext=6
onNext=7
onNext=7
onNext=8
onNext=8
onNext=9
onNext=9

3.过滤操作符

  1. debounce():事件流只发射规定范围时间内的数据项
  2. distinct():事件流只发射不重复的数据项
  3. elementAt():事件流只发射第N个数据项
  4. filter():事件流只发射符合规定函数的数据项
  5. fir
  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值