对于列表中的每个列表,执行操作直到满足条件

时间:2018-09-12 11:38:38

标签: java rx-java rx-java2

考虑以下代码:

void tryToOpenSafe() {
    getCorrectSafeCombination().subscribe(combination -> System.out.println("Correct combination is " + combination));
}

Maybe<Integer> getCorrectSafeCombination() {
    return getPossibleCombinations()
            .toObservable()
            .flatMapIterable(combinations -> combinations)
            .flatMap(combination -> tryToOpenSafeWithCombination(combination).toObservable()
                    .map(isCorrect -> new CombinationCheckResult(combination, isCorrect)))
            .filter(result -> result.isCorrect)
            .map(result -> result.combination)
            .firstElement();

}

Single<List<Integer>> getPossibleCombinations() {
    final List<Integer> combinations = Arrays.asList(123, 456, 789, 321);
    return Single.just(combinations);
}

// this is expensive
final Single<Boolean> tryToOpenSafeWithCombination(int combination) {
    System.out.println("Trying to open safe with " + combination);
    final boolean isCorrectCombination = combination == 789;
    return Single.just(isCorrectCombination);
}

我收到了可能要打开的保险箱的“组合”(整数)列表。当然,只有一种组合是正确的。

按照我目前的方法,getCorrectSafeCombination()将提供找到的第一个正确组合;但仍会尝试所有组合。

这是有效的:只要找到正确的组合,就无需尝试其他组合。

如何用Rx完成此操作?

1 个答案:

答案 0 :(得分:2)

之所以会发生这种情况,是因为flatMap用于在需要顺序观察时并发处理可观察对象。要解决此问题,您只需将flatMap更改为concatMap,以确保getCorrectSafeCombination方法中可观察对象的顺序流动:

Maybe<Integer> getCorrectSafeCombination() {
    return getPossibleCombinations()
            .toObservable()
            .flatMapIterable(combinations -> combinations)
            //this one
            .concatMap(combination -> tryToOpenSafeWithCombination(combination).toObservable()
                    .map(isCorrect -> new CombinationCheckResult(combination, isCorrect)))
            .filter(result -> result.isCorrect)
            .map(result -> result.combination)
            .firstElement();

}