3. RxJava转换操作符

转换类操作符顾名思义,就是将上游(被观察者)发送的数据进行转换成另一种形式(观察者希望接收的形式),从而使下游(观察者)能个正确的接受并作出响应;

这里介绍 map,flatMap,flatMapIterable,concatMap,switchMap,scan,cast,buffer,window,groupBy 进行讲解。

Student类

data class Student(var name: String,var score:Int)

1. map

对Observable发射的每一项数据应用一个函数,执行变换操作;

map操作符对原始Observable发射的每一项数据应用一个你选择的函数,然后返回一个发射这些结构的Observable

第一次转换,将字符串 “HELLO“ 转换成全是小写字母的字符串 ”hello“。第二次转换,在字符串 ”hello“ 后面添加新的字符串 ” world!“,它们组成了新的字符串也就是执行结果。所以map的作用就是将接收类型为T的Observable 转换成接收类型为R的Observable。

Observable.just("HELLO")
        .map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
                return s.toLowerCase(); //转为小写
            }
        })
        .map(new Function<String, String>() {
            @Override
            public String apply(String s) throws Exception {
                return s + " world!"; //加 world
            }
        })
        .subscribe(new Consumer<String>() { //订阅输出
            @Override
            public void accept(String s) throws Exception {
                System.out.println("Next: " + s);
            }
});
//运行结果
Next: hello world!

2. cast

cast运算符作用和map类似,但是它只能将父类对象转换为子类对象,是map的特殊版本

方法声明:Observable<R> cast(final Class<R> klass),将源事件类型转换成klass的数据类型。

  • 注意只能将父类对象转为子类对象;

  • cast执行转化必须是可以转的,如果该父类对象无法转为子类对象,会抛出classCastException异常;

List<Person> personList = new ArrayList<>(studentList);
Observable.from(personList)
    .cast(Student.class)
    .subscribe(student -> System.out.println(student.getId()));

3. flatMap

flatMap 将一个发射数据的Observable转变为多个Observables,然后将它们的数据合并后放入一个单独的Observable

flatMap 操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据Observable,然后flatMap 合并这些Observable发射的数据,最后将合并后的结构当做它自己的数据序列发射。

flatMap 对这些 Observables 发射的数据做的是合并 (merge) 操作, 因此它们可能是交错的。还有一个操作符不会让变换后 Observables 发射的数据交错,它严格按照顺序发射这些数据,这个操作符就是 concatMap

下面看一个例子,先定义一个用户对象,包含用名 和 地址由于地址可能包括生活、工作等地方,所以使用一个List对象来表示.

private class User {
    public String username;
    public List<Address> addresses;


    public static class Address {
        public String street;
        public String city;
    }
}

//使用 flatMap
public static void tesFlattMap() {
    List<User.Address> addresses = new ArrayList<>();
    addresses.add(new User.Address("北京"));
    addresses.add(new User.Address("上海"));
    addresses.add(new User.Address("宣化"));
    User user = new User();
    user.addresses = addresses;
    //如果想要打印出某个用户所有的地址,那么可以借助map操作符返回一个地址的列表。
    Observable.just(user)
            .map(new Function<User, List<User.Address>>() {
                @Override
                public List<User.Address> apply(@NonNull User user) throws Exception {
                    return user.addresses;
                }
            })
            .subscribe(new Consumer<List<User.Address>>() {
                @Override
                public void accept(List<User.Address> addresses) throws Exception {
                    for (User.Address address : addresses) {
                        System.out.println(address.city);
                    }
                }
            });


    //使用flatMap操作符后, flatMap内部将用户地址列表转换成一个Observable
    Observable.just(user)
            .flatMap(new Function<User, ObservableSource<User.Address>>() {
                @Override
                public ObservableSource<User.Address> apply(@NonNull User user) throws Exception {
                    return Observable.fromIterable(user.addresses);
                }
            })
            .subscribe(new Consumer<User.Address>() {
                @Override
                public void accept(User.Address address) throws Exception {
                    System.out.println(address.city);
                }
            });
}
//执行结果
北京
上海

4. flatMapIterable

flatMapIterable跟flatMap相差无几,区别在于flatMapIterable转换后的是一个Iterable对象,最后将所有的Iterable都传入一个Observable中,由这个Observable来将事件发送出去。

Observable.just(user)
        .flatMapIterable(new Function<User, Iterable<User.Address>>() {
            @Override
            public Iterable<User.Address> apply(@NonNull User user) throws Exception {
                return user.addresses;
            }
        }).subscribe(new Consumer<User.Address>() {
            @Override
            public void accept(User.Address address) throws Exception {
                System.out.println(address.city);
            }
        });

5. concatMap

concatMap操作符的功能和flatMap是非常相似的,只是有一点,concatMap 最终输出的数据序列和原数据序列是一致,

它是按顺序链接Observables,而不是合并(flatMap用的是合并)。

Observable.just(user)
        .concatMap(new Function<User, ObservableSource<User.Address>>() {
            @Override
            public ObservableSource<User.Address> apply(@NonNull User user) throws Exception {
                return Observable.fromIterable(user.addresses);
            }
        }).subscribe(new Consumer<User.Address>() {
            @Override
            public void accept(User.Address address) throws Exception {
                System.out.println(address.city);
            }
        });

6. switchMap

switchMap(Func1) 和 flatMap(Func1) 很像, 区分是,每当Observable发射一个新的数据项Observable时,它将取消订阅并停止监听之前那个数据项产生的Observable,并开始监视当前发射的这一个。

7. scan

san(Fun2)将前一事件产生的结果发送到下一个事件转换时的第一个参数使用;

Observable<T> scan(Func2<T, T, T> accumulator) 
Observable<R> scan(R initialValue, Func2<R, ? super T, R> accumulator) 

Observable.just(1, 2, 3, 4, 5)
        .scan(new BiFunction<Integer, Integer, Integer>() {
            @NonNull
            @Override
            public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                //把每次执行结果给第一个参数 Integer
                return integer + integer2;
            }
        })
        .subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                System.out.println(integer);
            }
        });
  //执行结果
    1
    3
    6
    10
    15

8. buffer

buffer就是将原有的事件转换成一个List列表,由一个新的Observable一次性发送出去,方法声明如下:

Observable<List<T>> buffer(int count)

Observable<List<T>> buffer(int count, int skip)

buffer 操作符将 Observable 变换为另一个,原来的Observable正常发射数据,由产生 Observable 发射这些数据的缓存集合。

buffer(count)

Observable.range(1, 10)
        .buffer(2) // 2个一组
        .subscribe(new Consumer<List<Integer>>() {
            @Override
            public void accept(List<Integer> integers) throws Exception {
                System.out.println("Next->" + integers);
            }
        });
//执行结果
Next->[1, 2]
Next->[3, 4]
Next->[5, 6]
Next->[7, 8]
Next->[9, 10]

buffer(count,skip)

Observable.range(1, 10)
        .buffer(2,3)
        .subscribe(new Consumer<List<Integer>>() {
            @Override
            public void accept(List<Integer> integers) throws Exception {
                System.out.println("Next->" + integers);
            }
        });
//执行结果
Next->[1, 2]
Next->[4, 5]
Next->[7, 8]
Next->[10]

9. window

window与buffer的作用非常相似,区别在于buffer发送出去的是一个列表List,而window发送出去的事件是一个Observable对象

Observable<Observable<T>> window(int count)

Observable<Observable<T>> window(int count, int skip)

Observable.range(1, 10)
        .window(2,3)
        .subscribe(new Consumer<Observable<Integer>>() {
            @Override
            public void accept(Observable<Integer> integerObservable) throws Exception {
                integerObservable.subscribe(integer -> System.out.println("Next->" + integer));
            }
        });
//执行结果
Next->1
Next->2
Next->4
Next->5
Next->7
Next->8
Next->10

10. groupBy

将一个Observable分拆为一些Observables集合,它们中的每一个发射原始Observable的一个子序列。

GroupBy操作符将原始Observable分拆为一些Observables集合,它们中的每一个发射原始Observable数据序列的一个子序列。

哪个数据项由哪个Observable发射是由函数判定的,该函数给每一项指定一个Key,Key相同的数据会被同一个Observable发射。

List<Student> students = new ArrayList<>();
students.add(new Student("U1111", 59));
students.add(new Student("U1112", 69));
students.add(new Student("U1113", 37));
students.add(new Student("U1114", 72));
students.add(new Student("U1115", 26));
students.add(new Student("U1116", 98));
students.add(new Student("U1117", 53));
students.add(new Student("U1118", 60));
students.add(new Student("U1119", 100));


Observable.fromIterable(students)
        .groupBy(new Function<Student, Integer>() {
            @Override
            public Integer apply(@NonNull Student student) throws Exception {
                return student.getScore() >= 60 ? 1 : 0;
            }
        })
        .subscribe(new Consumer<GroupedObservable<Integer, Student>>() {
            @Override
            public void accept(GroupedObservable<Integer, Student> integerStudentGroupedObservable) throws Exception {
                integerStudentGroupedObservable.subscribe(student -> {
                    if (integerStudentGroupedObservable.getKey() == 0) {
                        System.out.println("不及格ID: " + student.getName() +" ,score: "+ student.getScore());
                    } else {
                        System.out.println("及格ID: " + student.getName() +" ,score: "+ student.getScore());
                    }
                });
            }
        });
    //执行结果
    不及格ID: U1111 ,score: 59
    及格ID: U1112 ,score: 69
    不及格ID: U1113 ,score: 37
    及格ID: U1114 ,score: 72
    不及格ID: U1115 ,score: 26
    及格ID: U1116 ,score: 98
    不及格ID: U1117 ,score: 53
    及格ID: U1118 ,score: 60
    及格ID: U1119 ,score: 100

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值