【发布时间】:2017-09-22 08:20:51
【问题描述】:
我编写了以下代码,用于查找特定预算内的漫画 pageCount。
起初我试图提出具有这样架构的代码:
- Stream 提供 MarvelComic 对象的价格。
- 我将流中 MarvelComic 对象的价格与该流中之前的漫画价格相加,并检查它是否为 BUDGET
- 如果是,那么我将 MarvelComic 对象的 pageCount 与流下来的先前 MarvelComic 对象的 pageCount 总和相加。
- 如果是,则调用订阅者的 onNext。
由于我无法设计出一种方法来编写上述步骤中提到的代码,因此我求助于将命令式编程与反应式编程相结合。结果我写了以下代码:
Observable.fromIterable(getMarvelComicsList()).
map(new Function<MarvelComic, HashMap<String, Double>>() {
@Override
public HashMap<String, Double> apply(@NonNull MarvelComic marvelComic) throws Exception {
HashMap<String, Double> map = new HashMap<String, Double>();
map.put("price", Double.valueOf(marvelComic.getPrice()));
map.put("pageCount", Double.valueOf(marvelComic.getPageCount()));
map.put("comicCount", Double.valueOf(marvelComic.getPageCount()));
return map;
}
})
.scan(new HashMap<String, Double>(), new BiFunction<HashMap<String, Double>, HashMap<String, Double>, HashMap<String, Double>>() {
@Override
public HashMap<String, Double> apply(@NonNull HashMap<String, Double> inputMap, @NonNull HashMap<String, Double> newValueMap) throws Exception {
double sum = inputMap.get("price")+newValueMap.get("price");
double count = inputMap.get("pageCount")+newValueMap.get("pageCount");
double comicCount = inputMap.get("comicCount")+newValueMap.get("comicCount");
HashMap<String, Double> map = new HashMap<String, Double>();
map.put("price", sum);
map.put("pageCount", count);
map.put("comicCount", comicCount);
return map;
}
})
.takeWhile(new Predicate<HashMap<String, Double>>() {
@Override
public boolean test(@NonNull HashMap<String, Double> stringDoubleHashMap) throws Exception {
return stringDoubleHashMap.get("price") < budget;
}
})
.subscribe(new DisposableObserver<HashMap<String, Double>>() {
@Override
public void onNext(HashMap<String, Double> stringDoubleHashMap) {
double sum = stringDoubleHashMap.get("price");
double pageCount = stringDoubleHashMap.get("pageCount");
double comicCount = stringDoubleHashMap.get("comicCount");
Timber.e("sum %s pageCount %s ComicCount: %s", sum, pageCount, comicCount);
}
@Override
public void onError(Throwable e) {
Timber.e("onError %s", e.fillInStackTrace());
}
@Override
public void onComplete() {
Timber.e("onComplete");
}
});
我的预订:
- 每次在
map(), scan()中创建一个新的 Hashmap 是个好主意吗? - 如何进一步改进此代码?
问题:
这段代码在onError 中给出NullPointerException,因为map.get("price") 在scan() 中返回null。我不太确定原因。
错误:
onError java.lang.NullPointerException: Attempt to invoke virtual method 'double java.lang.Double.doubleValue()' on a null object reference
注意:
HashMap 不为空,由于某种原因,双字段被返回为 NULL。我想知道怎么做。
【问题讨论】:
-
为什么不使用具有
double字段和两个int字段的类而不是HashMap? -
是的,我想到了,但我认为与其创建一个单独的类,不如求助于一个集合将是一个更清洁的解决方案。即使我创建了另一个类,我也必须在mentinoed 方法中创建该类的对象
-
@DharmbirSingh 请发布问题并停止评论与此问题无关的内容。
-
我不认为
HashMap的这种使用特别干净。如果你按照我的建议,你不会遇到空指针异常的问题。 -
不过,就解决您当前的问题而言,您能做的最好的事情是使用调试器逐步执行此代码,以找出意外 null 的确切来源。
标签: java android rx-java observable rx-android