RxJava 学习笔记 -- 变换操作符

RxJava 基础知识

RxJava 学习笔记 -- 变换操作符

操作符作用
map()对序列的每一项都用一个函数来变换Observable发射的数据序列
flatMap()将Observable发射的数据集合变换为Observables集合,然后将这些Observable发射的数据平坦化的放进一个单独的Observable中
switchMap()将Observable发射的数据集合变化成Observable集合,然后只发射这些Observables 最近发射过的数据
scan()对Observable发射的每一项数据应用一个函数,然后按顺序依次发射每一个值
groupBy()将Observable拆分为Observable 集合,将原始Observable发射的数据按Key分组,每一个Observable发射一组不同的数据
buffer()定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是一次发射一个
window()定期将来自Observable的数据拆分成一些Observable窗口,然后发射这些窗口,而不是每次发射一项
cast()在发射之前强制将Observable发射的所有数据装换为指定类型

下面只列举一些常用的变换操作符的用法:

一. Map

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

fun testMap(){
        Observable.just("HELLO")
                .map {
                    //把大写转换成小写
                    it.toLowerCase()
                }
                .map {
                    //添加新的字符串
                    "$it MuFeng!"
                }
                .subscribeBy { Log.e("TAG",it) }
    }
复制代码

执行结果

09-07 03:01:11.820 9704-9704/com.mufeng.rxjavademo E/TAG: hello MuFeng!
复制代码
二. FlatMap

flatMap将一个发射数据的Observable变换为多个Observables,然后将他们发射的数据合并后放进一个单独的Observable

实际应用:
场景: 打印用户的所掌握的开发语言

  1. 我们需要先创建一个用户的数据类
data class User(var name: String, var languages: ArrayList<Language>)

data class Language(var name: String)
复制代码
  1. 我们分别用map和flatMap来实现
fun testFlatMap() {

            val language1 = Language("Android")
            val language2 = Language("Java")
            val language3 = Language("Kotlin")
            val language4 = Language("Python")

            val list = arrayListOf<Language>()
            list.add(language1)
            list.add(language2)
            list.add(language3)
            list.add(language4)

            val user = User("MuFeng", list)

            //map操作符实现
            Observable.just(user)
                    .map { user.languages }
                    .subscribeBy {
                        for (l in it) {
                            Log.e("TAG", l.name)
                        }
                    }

            Log.e("TAG", "----------------------------------")

            //flatMap操作符实现
            Observable.just(user)
                    .flatMap { user.languages.toObservable() }
                    .subscribeBy {
                        Log.e("TAG", it.name)
                    }

        }
复制代码

执行结果

09-07 11:27:53.354 12548-12548/com.mufeng.rxjavademo E/TAG: Android
    Java
    Kotlin
    Python
09-07 11:27:53.355 12548-12548/com.mufeng.rxjavademo E/TAG: ----------------------------------
09-07 11:27:53.357 12548-12548/com.mufeng.rxjavademo E/TAG: Android
    Java
    Kotlin
    Python
复制代码

我们发现执行的结果是一样的

flatMap对这些Observable发射的数据做的是合并操作,因此flatMap操作后的数据序列是无序的.如果要严格按照顺序发射这些数据请使用concatMap操作符

三. GroupBy

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

实际应用:
场景: 我们给出0-50把他们分成两组: 奇数组和偶数组,并打印出所有的偶数

  1. 我们先把0-50分成两组: 奇数组合偶数组
fun testGroupBy(){
            Observable.range(0,51)
                    .groupBy {
                        if (it % 2 == 0)
                            "偶数组"
                        else
                            "奇数组"
                    }
                    .subscribe {
                        //打印分组名称
                        Log.e("TAG","GroupName: ${it.key}")
                        //打印出所有偶数
                        if (it.key == "偶数组") {
                            it.subscribeBy { Log.e("TAG","偶数: $it") }
                        }
                    }
        }
复制代码

执行结果

09-07 06:09:36.984 1730-1730/com.mufeng.rxjavademo E/TAG: GroupName: 偶数组
    偶数: 0
    GroupName: 奇数组
    偶数: 2
    偶数: 4
    偶数: 6
    偶数: 8
09-07 06:09:36.985 1730-1730/com.mufeng.rxjavademo E/TAG: 偶数: 10
    偶数: 12
    偶数: 14
    偶数: 16
    偶数: 18
    偶数: 20
    偶数: 22
    偶数: 24
    偶数: 26
    偶数: 28
09-07 06:09:36.986 1730-1730/com.mufeng.rxjavademo E/TAG: 偶数: 30
    偶数: 32
    偶数: 34
    偶数: 36
    偶数: 38
    偶数: 40
    偶数: 42
    偶数: 44
    偶数: 46
    偶数: 48
09-07 06:09:36.988 1730-1730/com.mufeng.rxjavademo E/TAG: 偶数: 50
复制代码
四. Buffer

buffer 会定期收集Observable数据并放进一个数据包裹,然后发射这些数据包裹,而不是一次发射一个值
buffer 操作符将一个Observable变换成另一个,原来的Observable正常发射数据,由变换产生的Observable发射这些数据的缓存集合

fun testBuffer(){
            Observable.range(1,10)
                    .buffer(2)
                    .subscribeBy(
                            onNext = {Log.e("TAG",it.toString())},
                            onComplete = {Log.e("TAG","onComplete")}
                    )
        }
复制代码

执行结果

09-07 06:20:14.557 1996-1996/com.mufeng.rxjavademo E/TAG: [1, 2]
    [3, 4]
    [5, 6]
09-07 06:20:14.558 1996-1996/com.mufeng.rxjavademo E/TAG: [7, 8]
    [9, 10]
    onComplete
复制代码

buffer还有许多重载方法,比较常用的buffer(count,skip):
buffer(count,skip)从原始Observable的第一项数据开始创建新的缓存,此后每当收到skip项数据,就用count项数据填充缓存;开头的一项和后续的count-1项.它以列表List的形式发射缓存,这些缓存可能会有重叠的部分(当skip < count时),也可能会有间隙(当skip>count时),主要取决于count和skip的值

fun testBuffer(){
            Observable.range(1,10)
                    .buffer(5,1)
                    .subscribeBy(
                            onNext = {Log.e("TAG",it.toString())},
                            onComplete = {Log.e("TAG","onComplete")}
                    )
        }
复制代码

执行结果

09-07 06:30:03.621 1996-1996/com.mufeng.rxjavademo E/TAG: [1, 2, 3, 4, 5]
    [2, 3, 4, 5, 6]
    [3, 4, 5, 6, 7]
    [4, 5, 6, 7, 8]
    [5, 6, 7, 8, 9]
    [6, 7, 8, 9, 10]
09-07 06:30:03.622 1996-1996/com.mufeng.rxjavademo E/TAG: [7, 8, 9, 10]
    [8, 9, 10]
    [9, 10]
    [10]
    onComplete
复制代码

注意: 如果原来的Observable发射了一个onError通知,那么buffer 会立即传递这个通知,而不是首先发射缓存的数据,即使在这之前缓存中包含了原始Observable发射的数据

五. Window

定期将来自原始Observable的数据分解为一个Observable窗口,发射这些窗口,而不是每次发射一项数据

fun testWindow(){
            Observable.range(1,10)
                    .window(2)
                    .subscribeBy(
                            onNext = {
                                Log.e("TAG","onNext: ")
                                it.subscribeBy { Log.e("TAG","onNext: $it") }
                            },
                            onComplete = {Log.e("TAG","onComplete")}
                    )
        }
复制代码

执行结果

09-07 14:47:47.381 26617-26617/com.mufeng.rxjavademo E/TAG: onNext: 
09-07 14:47:47.382 26617-26617/com.mufeng.rxjavademo E/TAG: onNext: 1
    onNext: 2
    onNext: 
    onNext: 3
    onNext: 4
    onNext: 
09-07 14:47:47.383 26617-26617/com.mufeng.rxjavademo E/TAG: onNext: 5
    onNext: 6
    onNext: 
    onNext: 7
    onNext: 8
    onNext: 
    onNext: 9
09-07 14:47:47.384 26617-26617/com.mufeng.rxjavademo E/TAG: onNext: 10
    onComplete

复制代码

以上都是常用的变换操作符,下一篇回顾一下RxJava过滤操作符


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值