gpt4 book ai didi

java - 如何使用一个可观察值的状态来跳过另一个可观察值的值?

转载 作者:行者123 更新时间:2023-11-30 07:58:48 26 4
gpt4 key购买 nike

最好用一个简短的例子来解释。
假设这是我要过滤的可观察源

Observable.interval(1, TimeUnit.SECONDS)

我使用复选框来处理过滤器状态。未选中该框时,我想跳过所有值。
我使用 RxAndroid 来获取复选框的可观察值,如下所示:

RxCompoundButton.checkedChanges(checkBox)

这是我的代码:

    Observable.combineLatest(
RxCompoundButton.checkedChanges(checkBox)
, Observable.interval(1, TimeUnit.SECONDS)
, (isChecked, intervalCounter) -> {
if (!isChecked) {
return null;
} else {
return intervalCounter;
}
}
).filter(Objects::nonNull)

我得到了想要的输出

interval       1--2--3--4--5--6--7--8--9  
checkbox 0-----1--------0-----1---
combineLatest
result ------3--4--5--------8--9

我刚刚开始使用 RxJava,我的“解决方案”感觉不对,因为:
你可以看到 combine 函数返回了一个神奇的值 null 然后过滤器将跳过这些 nulls
这意味着即使我已经知道要跳过此数据,也会调用过滤器函数。

  • 也许我应该换个运营商
  • 有没有办法在过滤器函数中使用可观察复选框
  • 也许组合函数中有某种方式可以发出我想跳过此数据的信号

最佳答案

您所需输出的图片不正确。在您的实现中,combineLatestnull 组合到流中:

interval       1--2--3--4--5--6--7--8--9  
checkbox 0-----1--------0-----1---
combineLatest N--N--3--4--5--N--N--8--9
filter(NonNull)------3--4--5--------8--9

恕我直言,在 Rx Stream 中使用 null 作为信号并不好,开发人员很容易陷入 NullPointerException

要避免使用null,有两种措施。第一个是将结果转换为 Pair,然后应用 filter & map。

一个非常简单的Pair类:

public class Pair<T, U> {
T first;
U second;

public Pair(T first, U second) {
this.first = first;
this.second = second;
}
}

那么整个实现是这样的:

Observable.combineLatest(
RxCompoundButton.checkedChanges(checkBox)
, Observable.interval(1, TimeUnit.SECONDS)
, (isChecked, intervalCounter) -> new Pair<>(isChecked,intervalCounter)
).filter(pair -> pair.first)
.map(pair -> pair.second) // optional, do this if you only need the second part

数据流:

interval          1      2      3      4
| | | |
checkbox F | T | F | T F
| | | | | | |
combineLatest F1 T1 T2 F2 F3 T3 F4
| | |
filter(first=T) T1 T2 T3
| | |
map(second) 1 2 3

或者,如果您可以在您的项目中使用 Java 8,请使用 Optional 来避免 null,这与您的解决方案非常相似,但它让其他开发人员意识到流信号是可选的

Observable<Optional<Integer>> o1 = Observable.combineLatest(
RxCompoundButton.checkedChanges(checkBox)
, Observable.interval(1, TimeUnit.SECONDS)
, (isChecked, intervalCounter) -> {
if (!isChecked) {
return Optional.empty();
} else {
return Optional.of(intervalCounter);
}
}
)

Observable<Integer> o2 = o1.filter(Optional::isPresent).map(Optional::get)

一些更简单的方法,与 combineLatest 不同,但与您想要的结果图片相同。

// Approach 1
Observable.interval(1, TimeUnit.SECONDS).filter( i -> checkBox.isEnabled())

// Approach 2
Observable.interval(1, TimeUnit.SECONDS)
.withLatestFrom(
RxCompoundButton.checkedChanges(checkBox),
(isChecked, intervalCounter) -> {
if (!isChecked) {
return Optional.empty();
} else {
return Optional.of(intervalCounter);
}
}).filter(Optional::isPresent).map(Optional::get)

关于java - 如何使用一个可观察值的状态来跳过另一个可观察值的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40058777/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com