如何对Iterable执行FlatMap并重组?RxJava如何过滤Single<List>中的值
嘿,我来帮你搞定这两个RxJava的问题,直接上解决方案和代码示例!
问题1:对Iterable执行FlatMap并重组为Iterable
要对一个Iterable做FlatMap操作,核心思路是先把它转换成RxJava的Observable流,通过FlatMap展开嵌套的元素,最后再重新收集成Iterable(比如List)。这里分两种场景给你示例:
异步非阻塞场景(推荐)
如果是在异步流程里,我们可以把结果收集成Single<List<T>>,List本身就是Iterable的实现类:
import io.reactivex.rxjava3.core.Observable; import io.reactivex.rxjava3.core.Single; import java.util.Arrays; import java.util.List; public class FlatMapIterableExample { public static void main(String[] args) { // 原始Iterable:每个元素是一个子列表 Iterable<List<String>> sourceIterable = Arrays.asList( Arrays.asList("apple", "banana"), Arrays.asList("orange", "grape") ); // 执行FlatMap并重组为Single<List<String>> Single<List<String>> resultSingle = Observable.fromIterable(sourceIterable) .flatMap(subList -> Observable.fromIterable(subList)) // 展开每个子列表 .toList(); // 收集所有元素为List // 订阅结果 resultSingle.subscribe(filteredList -> { System.out.println("FlatMap后的结果:" + filteredList); // filteredList就是我们需要的Iterable }); } }
同步阻塞场景
如果需要直接获取Iterable(同步阻塞方式),可以用blockingIterable():
Iterable<String> resultIterable = Observable.fromIterable(sourceIterable) .flatMap(subList -> Observable.fromIterable(subList)) .blockingIterable(); // 遍历结果 for (String item : resultIterable) { System.out.println(item); }
问题2:过滤Single<List>并返回新的Single
你的测试用例里没必要先转成Observable,Single本身提供的map操作符就能直接对内部的List做过滤,代码更简洁。当然也可以用Observable的方式实现,两种方案都给你:
方案1:直接用Single的map操作(推荐)
import io.reactivex.rxjava3.core.Single; import org.junit.Test; import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import static org.junit.Assert.assertEquals; public class FilterSingleListTest { @Test public void filterTest() { List<String> sourceList = Arrays.asList("email", "phone", "smoke", "email", "phone", "fax", "email"); // 过滤出"email"和"phone",返回Single<List<String>> Single<List<String>> filteredSingle = Single.just(sourceList) .map(list -> list.stream() .filter(item -> item.equals("email") || item.equals("phone")) // 自定义过滤条件 .collect(Collectors.toList())); // 验证结果 filteredSingle.test() .assertValue(filteredList -> { assertEquals(5, filteredList.size()); // 3个email + 2个phone = 5个元素 return filteredList.stream().allMatch(item -> item.equals("email") || item.equals("phone")); }); } }
方案2:转成Observable再处理
如果你坚持用Observable的方式,用flatMapIterable展开列表元素,过滤后再收集成Single:
@Test public void filterTestWithObservable() { List<String> sourceList = Arrays.asList("email", "phone", "smoke", "email", "phone", "fax", "email"); Single<List<String>> filteredSingle = Single.just(sourceList) .toObservable() .flatMapIterable(list -> list) // 把List转成每个元素的Observable流 .filter(item -> item.equals("email") || item.equals("phone")) // 过滤单个元素 .toList(); // 重新收集成List并转成Single // 验证结果 filteredSingle.test() .assertValue(filteredList -> filteredList.size() == 5); }
内容的提问来源于stack exchange,提问作者shadox
相关产品推荐
相关产品推荐

