我正在尝试使用作者ID键这样的消息图:
Map<Long, Collection<Message>>
这是我尝试过的:
messageViewModel.getAll()
.flatMap(Flowable::fromIterable)
.toMultimap(Message::getAuthorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
private void onSuccess(Map<Long, Collection<Message>> longCollectionMap) {
Collection<Message> messages = longCollectionMap.get(0);
}
messageViewModel.getAll()方法返回:
Flowable<List<Message>>
因此,我将其转换为Flowable流(Flowable :: fromIterable),使其一次可以发射一个项目而不是整个列表,然后使用“ toMultiMap”进行映射。
从不调用onSuccess方法,我不知道这里出了什么问题。如果我不使用toMultiMap(并且对代码进行了相应的修改),它可以工作,那么问题一定是toMultiMap方法。
但是当我尝试这样做时:
List<String> list = Arrays.asList("1", "2", "3");
Flowable.fromIterable(list)
.toMultimap(String::length)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
private void onSuccess(Map<Integer,Collection<String>> integerCollectionMap) {
Collection<String> strings = integerCollectionMap.get(1);
}
这有效!唯一的区别是,此数据库不调用会议室数据库来获取可迭代项。
文档也说:
请注意,此运算符要求上游发出{@code onComplete}信号,以发出累积的地图。
这使我感到困惑。由于Flowable类没有使用onComplete作为参数的订阅方法,并且在上面显示的第二种情况下也没有使用它,但是它可以工作。
请帮助我,这使我发疯。
答案 0 :(得分:0)
我为遇到相同或相似问题的任何人找到了解决方案。
首先,我必须调试以查看映射是否实际完成。为此,我只是从toMultiMap方法开始对其进行了调试。然后我发现映射实际上已经完成了,所以问题是结果没有返回。
阅读有关RxJava的更多信息,我意识到了问题的原因。第一次通话:
messageViewModel.getAll()
返回
Flowable<List<Message>>
这意味着此源将发出0到n个元素,在这种情况下为Message的“列表”。确实,它发出了Message列表,然后映射完成。但是它没有返回任何内容,因为它正在等待源中出现更多的“列表”。
您必须记住,Flowable或Observable可能会发出无限个元素。与Flowable.fromIterable的区别在于,fromIterable将停止,或者在发出作为参数传递的iterable的最后一个元素后,信号流已结束,这意味着方法序列的其余部分将不再等待更多元素,结果将返回。
因此解决方案是将messageViewModel.getAll()的返回类型更改为:
Single<List<Message>>
因此,它现在将发出1个项目,消息列表或一个错误。因此,发出一个元素后,将不再有其他元素,链上的其他方法将执行并返回该值。
但是“ toMultiMap”方法不适用于“ Single”,但是Single类上没有这样的东西。因此,您必须将其转换为可流动的,所以我做到了:
.flatMapPublisher(Flowable::fromIterable)
所以最后,代码如下所示:
messageViewModel.getAll() //Returns Single<List<Message>>
.flatMapPublisher(Flowable::fromIterable) // Creates a flowable from List<Message>
.toMultimap(Message::getAuthorId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onSuccess);
非常干净的代码,花一些时间来了解反应式方法的工作原理,但是绝对值得。希望有人觉得这有用。
答案 1 :(得分:0)
您还可以使用:
Map<Long, Collection<Message>> myMap = messageViewModel.getAll()
.flatMap(message ->
Observable.fromIterable(message)
.toMultimap(Message::getAuthorId)
.toObservable());