前言

为了方便自己查询,也为了重温一些常用的操作符,在这里列个索引,包括RxJava操作符,Java8 Stream API,Kotlin高阶函数,总体看来三者在设计上有很多相似之处
因为仅仅是索引,为了简洁直观、方便查询不会去具体分析每个操作符的用法,如果想了解具体用法可以去看文末的参考文章

RxJava篇

0.创建型操作符

  • create(onSubscribe)
    通过OnSubscribe对象创建Observable

  • just(T)
    依次发射传入的参数

  • from(Array/Iterator)
    拆解数组/容器中的元素并依次发射

  • defer(Func0)
    配合创建操作符,做到订阅后才会开始创建

  • repeat(int)
    配合创建操作符,重复数次创建发射的数据

  • range(int, int)
    依次发射一个数字区间的数字

  • interval(int, int, Unit)
    轮询发射,参数依次为起始延迟时间,轮询时间间隔,时间单位

  • timer(int, Unit)
    延迟发射,参数为延迟时间,时间单位

1.转换操作符

  • map(Func1)
    类型转化A -> B

  • flapMap(Func1)
    类型转化,返回Observable<T>,A -> Observable

  • concatMap(Func1)
    flapMap返回的结果是不能保证和传入顺序一致的,可能会交叉,concapMap则是依序的

  • flatMapIterable(Func1)
    与flapMap类似,要求返回Iterable<T>,并将该集合依次发射

  • switchMap(Func1)
    与flapMap类似,当数据源发出新数据时,会停止发射上一个数据源转化产生的Observable,开始处理当前需要转化的数据

  • scan(Func2)
    类型转化,将当前两个数据源A与B转化后的结果作为下一次转化的A数据,与新数据B继续转化

  • groupBy(Func1)
    基于一个Key,将数据源中Key相同的数据划分到同一组,产生多个组,并将每组的数据依次发射

  • buffer(int)
    收集结果,每集齐n个发射一次集合

  • buffer(int, Unit)
    收集结果,每集齐一段时间发射一次集合

  • window(int, Unit)
    同Buffer类似,但返回的是Observable包裹的集合

  • cast(Class)
    将每个数据都强转成该class类型再发射

2.过滤操作符

  • filter(Func1)
    过滤表达式结果为false的数据

  • take(int)
    发射前n项

  • takeLast(int)
    发射后n项

  • takeUntil(Func1)
    发射,直到表达式结果为true停止发射

  • takeUntil(Observable)
    发射,直到参数中的Observable开始发射时停止发射

  • skip(int)
    跳过前n项

  • skipLast(int)
    跳过后n项

  • elementAt(int)
    发射第n项

  • debounce(long, Unit)
    如果在指定的时间间隔中没有发射一个数据,那么它将发射最后的那个(即一个数据在下一个数据到来前停留了足够的间隔才会发射,常用于点击间隔,搜索间隔等)

  • sample(long, Unit)
    发射每个时间间隔中最近的一个元素

  • throttleFirst(long, Unit)
    发射每个时间间隔中第一个元素

  • timeout(long, Unit)
    指定时间间隔没发射值则产生onError

  • distinct()
    过滤重复的数据

  • distinctUntilChanged()
    只判断和前一项是否重复,重复则过滤

  • first()
    只发射第一项

  • first(Func1)
    发射第一个满足条件的项

  • last()
    只发射最后一项

  • last(Func1)
    只发射最后一个满足条件的项

3.组合操作符

  • merge(Observable, Observable)
    合并两个Observable中的数据并依次发射,合并后是无序的

  • merge(Observable[])
    同上

  • concat(Observable<? extends T>, Observable<? extends T>)
    先发射前者的数据,再发射后者的数据,相比merge有序了

  • startWith(T)
    在源数据前插入一组数据

  • startWith(Observable)
    同上,发射时先发射参数Observable中的数据,即也是插入数据到前面

  • zip(Observable, Observable, Func2)
    合并两个Observable中的数据,每次从两者中各取一个数据根据Func2规则做转化后发射,其中一个Observable发射结束或出现异常则结束

  • combineLatest(Observable, Observable, Func2)
    合并两个Observable中的数据,在每一个新数据发射时都取另一个Observable中最近一次发射数据根据Func2规则做转化后发射

  • join(Observable, Func1, Func1, Func2)
    类似zip和combineLatest,将源数据与参数中的Observable结合后根据Func2作转换后发射,不过第一个Func1决定了源数据的声明有效期,第二个Func1则决定了参数Observable数据的声明有效期,每个新数据发射后都会与另一个Observable中尚在声明有效期内的所有数据都产生结合

附录 Scheduler种类

种类 效果
Schedulers.computation() 用于计算任务,如事件循环或和回调处理,不要用于IO操作(IO操作请使用Schedulers.io());默认线程数等于处理器的数量,它是buffer() , debounce() , delay() , interval() , sample() , skip()方法默认的调度器
Schedulers.from(executor) 使用指定的Executor作为调度器
Schedulers.immediate() 在当前线程立即开始执行任务,它是 timeout() , timeInterval() ,以及 timestamp() 方法默认的调度器
Schedulers.io() 用于IO密集型任务,如异步阻塞IO操作,这个调度器的线程池会根据需要增长;对于普通的计算任务,请使用Schedulers.computation();Schedulers.io()默认是一个CachedThreadScheduler,很像一个有线程缓存的新线程调度器
Schedulers.newThread() 为每个任务创建一个新线程
Schedulers.trampoline() 当其它排队的任务完成后,在当前线程排队开始执行,它是 repeat() 和 retry() 方法默认的调度器
AndroidSchedulers.mainThread() RxAndroid中的类型,表示Android主线程

附录 Subject种类

种类 效果
PublishSubject 常规情况,在订阅后开始发送数据
BehaviorSubject 在订阅者订阅时,会先发送一个其最近发送的数据(如果此时还没有收到任何数据,它会发送一个默认值),然后正常发送订阅后的数据
ReplaySubject 在订阅时,会发送所有的数据给订阅者,即使是订阅前已经发射的数据
AsyncSubject 只会在Observable发射完结后,将发出的最后一个数据发给订阅者

Java8 stream API篇

create型

Stream的一系列静态工厂方法

  • of(T t)
  • of(T… values)
    返回含有一个或多个T元素的stream

  • generate(Supplier s)
    返回一个无限长度的stream,通常要配合过滤或终结操作符使之变为有限长度的

  • iterate(T seed, UnaryOperator f)
    返回seed,f(seed),f(f(seed)) … 类型的无限长度的stream

  • empty()
    返回空的stream

Intermediate型

Intermediate型的方法返回结果为stream类型,可以像链式一样多次调用

  • concat(Stream, Stream)
    按先后有序拼接两个stream中的数据

  • distinct()
    剔除重复元素

  • filter(Predicate)
    过滤不满足条件的元素

  • map(Func)
    转换元素

  • flatMap(Func)
    转换元素,要求返回一个stream类型

  • peek(Consumer)
    创建一个包含原Stream的所有元素的新Stream,对其中的每个元素执行一次Consumer处理,原流不变,直接返回

  • skip(long)
    跳过前n个元素,从n+1起返回一个新流

  • sorted()

  • sorted(Comparator)
    按规则对流排序

Terminal型

Terminal型的方法返回结果为void或非stream类型,在数据流中只能使用一次

  • count()
    返回流中元素的个数

  • forEach(Consumer)
    遍历元素,对每个元素执行一次Consumer处理

  • forEachOrdered(Consumer)
    保证依照原顺序遍历元素,对每个元素执行一次Consumer处理,并行流中forEach可能会乱序

  • max(Comparator)
    返回最大值

  • min(Comparator)
    返回最小值

  • reduce(BinaryOperator)

  • reduce(T, BinaryOperator)
  • reduce(U, BiFunction, BinaryOperator)
    有三个重载方法,类似RxJava中的scan,将两个元素的操作结果作为下一次操作的元素之一,与新元素再次操作,返回最终结果 具体参考

  • collect(Supplier, BiConsumer, BiConsumer)

  • collect(Collector)
    有两个重载方法,非常强大的操作符,可以将流转化成各种数据结构类型返回 具体参考

Short-circuiting型

Short-circuiting型的方法可以有效的处理无限元素的stream

  • limit(long)
    返回前n个元素组成的新流

  • allMatch()
    顾名思义,所有元素满足条件才会返回true,否则返回false

  • anyMatch()
    有元素满足条件就会返回true,否则返回false

  • noneMatch()
    所有元素都不满足条件则返回true,否则返回false

  • findAny()
    返回随机一个元素的Optional

  • findFirst()
    返回第一个元素的Optional

Kotlin高阶函数篇

0.集合操作符

非常非常丰富,和上面的rxjava, stream操作符有很多类似之处,一共有6类:

  • 总数操作符
  • 过滤操作符
  • 映射操作符
  • 顺序操作符
  • 生产操作符
  • 元素操作符

已经有文章例举的很全面了,具体参考戳这里

1.apply/with

通过上下文帮助我们调用方法,而且由于上下文是依赖注入的,还可以灵活切换

1
2
3
4
5
6
7
8
9
10
11
12
textView.apply {
scale = 2f
rotationX = 10f
}
//等同于
with(textView) {
scale = 2f
rotationX = 10f
}
//等同于
textView.scale = 2f
textView.rotationX = 10f

2.let

let中传入的lambda调用的参数就是它自己,是一个灵活的操作符,可以封装一些操作,可以有返回值

1
2
3
4
textView?.let{
it.scale = 2f
it.rotationX = 10f
}

3.run

执行一个代码块,类似于执行了一个匿名函数,可以有返回值

1
run { }

4.repeat

将代码块重复执行数次,lambda传入的参数(it)是索引

1
2
3
repeat(3) {
print("index:$it")
}

5.to

产生Pair类型的对象

1
2
val map = mapOf(1 to "x", 2 to "y", -1 to "zz")
println(map) // {1=x, 2=y, -1=zz}

6.lazy

起到延迟加载的效果,在第一次调用时才加载

1
2
3
4
5
6
7
8
9
10
11
class TestActivity : Activity(){
val mTextView: TextView by lazy{
findViewById(R.id.tv_test) as TextView
}
override fun onCreate(savedInstanceState: Bundle?){
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mTextView = "Test"
}
}

更多高阶函数可以参考官网

参考文章

RxJava系列2(基本概念及使用介绍)
Java 8系列之Stream的基本语法详解
Kotlin一些高阶函数的使用

声明:本站所有文章均为原创或翻译,遵循署名-非商业性使用-禁止演绎 4.0 国际许可协议,如需转载请确保您对该协议有足够了解,并附上作者名(Est)及原贴地址