我是RxJava2的新手。
我正在尝试从缓存和服务器获取事务对象的列表。 我想将服务器值与缓存值进行比较,如果服务器值相同,则将其忽略。
我能够使用.scan()轻松地完成此操作,因为我们可以返回null,而当从.scan()返回null时,该值将被忽略(过滤)。
RxJava 1
private Observable<List<Transaction>> getTransactionsFromCacheAndServer() {
return Observable.concat(
getTransactionsFromCache(),
getTransactionsFromServer()
)
.scan((p1, p2) -> {
if (p1 == null && p2 != null) {
return p2;
} else if (p1 != null && !isListSame(p1, p2)) {
return p2;
} else {
return null;
}
});
}
使用RxJava 2,由于我再也无法返回null,所以事情变得不容易。
RxJava 2
private Observable<List<Transaction>> getTransactionsFromCacheAndServer() {
return Observable.concat(
getTransactionsFromCache(),
getTransactionsFromServer()
)
.map(FilterObject::new)
.scan((filterObject1, filterObject2) -> {
List<Transaction> p1 = (List<Transaction>)filterObject1.value;
List<Transaction> p2 = (List<Transaction>)filterObject2.value;
if (p1.size() == 0 && p2.size() > 0) {
return filterObject2;
} else if (!isListSame(p1, p2)) {
return filterObject2;
} else {
filterObject2.filter = true;
return filterObject2;
}
})
.filter(filterObject -> !filterObject.filter)
.map(filterObject -> (List<Transaction>)filterObject.value);
}
其中FilterObject是:
public class FilterObject {
public Object value;
public boolean filter;
public FilterObject(Object value) {
this.value = value;
}
}
即使使用上述方法也可以实现相同的目的,但看起来却很丑陋。另外,我还必须包括两个性能可能不太友好的地图。
是否有简单/干净的方法来实现我想要的?
答案 0 :(得分:2)
我认为没有通用的解决方案,因为一个空列表和一个需要过滤的列表(在所有情况下碰巧都是空的)是两种不同的东西(扫描的输出)并且需要以不同的方式处理。
但是,在您的特定情况下,您从不发出空列表,除了可能用于第一个输出。
(我使用String
代替Transaction
,没关系)
private Observable<List<String>> getTransactionsFromCacheAndServer() {
return Observable.concat(
getTransactionsFromCache(),
getTransactionsFromServer()
)
.filter(list -> !list.isEmpty())
// If you prefer a consistent empty list over the first
// empty list emission getting filtered
.startWith((List<String>) Collections.EMPTY_LIST)
// Newly emitted value cannot be empty, it only depends only on the comparison
.distinctUntilChanged(this::isListSame);
}
这是我用最少的运算符可以获得的最接近的结果。希望它能解决您的问题。
答案 1 :(得分:1)
基于andras' answer,我做了一些修改以实现我想要的。
private Observable<List<String>> getTransactionsFromCacheAndServer() {
return Observable.concat(
getTransactionsFromCache(),
getTransactionsFromServer()
)
.filter(list -> !list.isEmpty())
.distinctUntilChanged(this::isListSame)
.switchIfEmpty(Observable.just(new ArrayList<>()));
}
安德烈亚斯(Andreas)的答案将始终收到一个空列表,然后是真实数据。
我上面的解决方案将收到:
1.缓存中的数据(如果不同则从服务器中获取数据)
2.如果缓存和服务器均返回“空列表”,则为空列表。