RxJava中将大列表拆分为分块列表的问题求助
为什么RxJava的window和buffer操作符没有正确拆分我的大列表?
我一眼就看出问题出在哪了——你误解了Observable.just()的行为:它并没有把列表里的元素逐个发射出去,而是把整个列表对象当成了单个发射项。这就导致window(2)和buffer(2)都是针对这一个列表对象进行操作,自然没法拆分成你想要的小分块。
先看window操作符的问题与修正
你的原代码里,Observable.just(mutableListOf(1,2,3,4,5,6))只发射了1个元素(就是那个完整的列表),window(2)尝试把这1个元素分成每2个一组,结果只能得到包含这个完整列表的单个窗口。
修正的核心是:用Observable.fromIterable()代替just(),它会把列表里的每个元素逐个发射,这样window才能正确分组。另外,window返回的是Observable<Observable<T>>,你需要把每个窗口转换成List才能看到分块结果:
Observable.fromIterable(mutableListOf(1,2,3,4,5,6)) .window(2) .flatMap { windowObservable -> windowObservable.toList() } .subscribe { chunk -> println("This is a chunk of 2 numbers -> $chunk") }
运行这段代码,你会得到预期的输出:
This is a chunk of 2 numbers -> [1, 2] This is a chunk of 2 numbers -> [3, 4] This is a chunk of 2 numbers -> [5, 6]
再看buffer操作符的问题与修正
同样的根源:原代码里just()只发射了单个列表,buffer(2)把这一个列表放进缓冲区,结果就得到了包含这个完整列表的列表(也就是[[1,2,3,4,5,6]])。
修正后只需要把just()换成fromIterable(),而且你原代码里的flatMap是多余的——因为buffer()本身就会直接发射分好组的List:
Observable.fromIterable(mutableListOf(1,2,3,4,5,6)) .buffer(2) .subscribe { chunk -> println("This is a chunk of 2 numbers -> $chunk") }
这段代码的输出和window修正后的结果完全一致,而且代码更简洁——如果你只是需要把元素分块成List,buffer()通常比window()更直接好用。
关键知识点总结
Observable.just(list):发射单个List对象,适合传递整个集合的场景Observable.fromIterable(list):逐个发射List中的每个元素,适合需要对集合内元素逐个处理的场景window():将源Observable拆分成多个Observable窗口,每个窗口包含指定数量的元素,适合需要对窗口做Observable级操作的场景buffer():直接将源Observable的元素收集成List分块,适合单纯需要分块列表的场景
内容的提问来源于stack exchange,提问作者Tarcisio Wensing
相关产品推荐
相关产品推荐

