You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:29:05