如何帮助Java解析我的RxJava组合方法中的类型?

时间:2017-06-02 10:07:22

标签: java rx-java2

我想链接两个RxJava Single实例来创建一个Observable,它会发出两个结果。另外,我需要第一个Single的结果来创建第二个。public static <A extends C, B extends C, C> Observable<C> chain(final Single<A> a, final Function<A, Single<B>> f) { return Observable.concat( a.toObservable(), a.flatMap(f::apply).toObservable()); }

以下是我的尝试:

final Observable<Event> task = MoreObservables.chain(
    writeFile("Hello, world", "hello.txt"),
    writeFileEvent -> processFile(writeFileEvent.path));

用法可能如下所示:

Error:(54, 61) java: incompatible types: cannot infer type-variable(s) A,B,C
(argument mismatch; bad return type in lambda expression
  io.reactivex.Single<ProcessFileEvent> cannot be converted to io.reactivex.Single<Event>)

然而,Java抱怨它无法解析类型:

ProcessFileEvent

当然,Event实现public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) { return reduce(BinaryOperator.maxBy(comparator)); }

如何编写我的函数以便Java可以找出类型?或者有更简单的方法来实现这个?

1 个答案:

答案 0 :(得分:2)

如果不知道确切的writeFileprocessFile签名(来自简单模拟,它应该编译),很难说出为什么会出现编译错误。

无论如何,更惯用的方法是使用compose()方法和自定义ObservableTransformer,以便拥有一个链而不是包装方法,使链变得不那么可读(read this) 。
这里也存在逻辑问题,因为您正在使用concat()并使用两次Observable,您实际上将执行两次操作(将被订阅两次),这可能导致最糟糕情况下的性能问题,或者是一个主要的微妙错误。 (在您的示例中,您将两次写入同一文件) 我认为你应该在这种情况下使用publish,为了执行一次,与merge一起执行,这将导致Observable将发出A的结果,然后执行B结果为A,并将发出此结果:

变压器:

class PublishAndMergeTransformer<A extends C, B extends C, C> implements ObservableTransformer<A, C> {

        final Function<A, Single<B>> f;

        public PublishAndMergeTransformer(Function<A, Single<B>> f) {
            this.f = f;
        }

        @Override
        public ObservableSource<C> apply(Observable<A> a) {
            return a.publish(aObservable ->
                    Observable.merge(
                            aObservable,
                            aObservable
                                    .flatMap(a1 -> f.apply(a1).toObservable())
                    )
            );
        }
    }

和使用示例:

writeFile("Hello, world", "hello.txt")
    .toObservable()
    .compose(new PublishAndMergeTransformer<>(writeFileEvent -> processFile(writeFileEvent.path)));