Rx java 在RxJava2中处理null

Rx java 在RxJava2中处理null,rx-java,Rx Java,接下来的一个重要变化是,null不再被接受为流元素,即以下代码将抛出异常:Observable.just(null) 老实说,我对这一变化的感受是复杂的,我的一部分人理解这将强制执行干净的API,但我可以看到许多可能出现问题的用例 例如,在我的应用程序中,我有一个内存缓存: @Nullable CacheItem findCacheItem(long id); 缓存中可能不存在CacheItem,因此方法可能返回空值 与Rx*一起使用的方式如下: Observable<CacheItem

接下来的一个重要变化是,
null
不再被接受为流元素,即以下代码将抛出异常:
Observable.just(null)

老实说,我对这一变化的感受是复杂的,我的一部分人理解这将强制执行干净的API,但我可以看到许多可能出现问题的用例

例如,在我的应用程序中,我有一个内存缓存:

@Nullable CacheItem findCacheItem(long id);
缓存中可能不存在CacheItem,因此方法可能返回空值

与Rx*一起使用的方式如下:

Observable<CacheItem> getStream(final long id) {
    return Observable.fromCallable(new Callable<CacheItem>() {
        @Override public CacheItem call() throws Exception {
            return findCacheItem(id);
        }
    });
}
使用RxJava2,我不再被允许在流中发布
null
,因此我要么需要将我的CacheItem包装到其他类中,让流生成该包装器,要么进行相当大的架构更改

在我看来,将每个流元素包装成可为空的对应元素并不合适

我是不是错过了一些基本的东西

看起来像我这样的情况很流行,所以我很好奇,在RxJava2中有了新的“非空”策略后,解决这个问题的推荐策略是什么

编辑
请参见

中的后续对话。好吧,有几种方法可以表达您的需求

一种选择是使用
可观察的

可观察的getStream(最终长id){
返回可观察。延迟(()->{
返回可观察的.just(可选的.ofNullable(findCacheItem(id));
});
}
公共静态变压器去优化(){
返回src->
src.flatMap(item->item.isPresent()
?可观察的.just(item.get())
:可见。空();
}

然后使用
.compose(deoptionalize())
从可选的可观察对象映射到非可选的可观察对象。

作为另一种解决方案,您可以添加静态实例CacheItem.NULL,并在没有缓存数据时将其返回给订阅服务器

Single
    .concat(loadFromMemory(), loadFromDb(), loadFromServer())
    .takeFirst { it != CachedItem.NULL }
    .subscribe(
您可以使用来处理RxJava2中的空值

根据您的情况,您可以:

Observable<CacheItem> getStream(final long id) {
    return RxNullable.fromCallable(() -> findCacheItem(id))
                     .onNullDrop()
                     .observable();
}
Observable.just(user)
          .map(user -> user.getName())
          .map(name -> convertNameToId(name))
          .flatMap(id -> getStream(id).onNullRun(() -> showPrompt()))
          .map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
          .subscribe(userInfo -> showUserInfo());

NullableObservable<CacheItem> getStream(final long id) {
    return RxNullable.fromCallable(() -> findCacheItem(id)).observable();
}

可能的解决方案是使用
Maybe.switchIfEmpty

例如:

public static <T> Maybe<T> maybeOfNullable(T value) {
    return value == null ? Maybe.empty() : Maybe.just(value);
}

maybeOfNullable(user)
        .map(user -> user.getName())
        .map(name -> convertNameToId(name))
        .flatMap(id -> getStream(id))
        .map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
        // perform another action in case there are no any non null item emitted
        .switchIfEmpty(Maybe.fromAction(() -> showPrompt()))
        .subscribe(userInfo -> showUserInfo());
公共静态可能不可用(T值){
返回值==null?Maybe.empty():Maybe.just(value);
}
可能不可用(用户)
.map(用户->用户.getName())
.map(名称->转换名称ID(名称))
.flatMap(id->getStream(id))
.map(cacheItem->getUserInfoFromCacheItem(cacheItem))
//如果没有发出任何非空项,则执行另一个操作
.switchIfEmpty(可能是.fromAction(()->showPrompt()))
.subscribe(userInfo->showUserInfo());
Observable.just(user)
          .map(user -> user.getName())
          .map(name -> convertNameToId(name))
          .flatMap(id -> getStream(id).onNullRun(() -> showPrompt()))
          .map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
          .subscribe(userInfo -> showUserInfo());

NullableObservable<CacheItem> getStream(final long id) {
    return RxNullable.fromCallable(() -> findCacheItem(id)).observable();
}
public static <T> Maybe<T> maybeOfNullable(T value) {
    return value == null ? Maybe.empty() : Maybe.just(value);
}

maybeOfNullable(user)
        .map(user -> user.getName())
        .map(name -> convertNameToId(name))
        .flatMap(id -> getStream(id))
        .map(cacheItem -> getUserInfoFromCacheItem(cacheItem))
        // perform another action in case there are no any non null item emitted
        .switchIfEmpty(Maybe.fromAction(() -> showPrompt()))
        .subscribe(userInfo -> showUserInfo());