0

How can I rewrite this via a Java Lambda?

This question is different from "Lambda Expression and generic method" issue. The issue is because of throwing an Exception.

public Observable<String> getUserInfo() {
    return Observable.create(new ObservableOnSubscribe<String>() {
        @Override
        public void subscribe(ObservableEmitter<String> emitter) throws Exception {
            try {
                emitter.onNext( getPlayerInfo());
                emitter.onComplete();
            } catch (Exception e) {
                emitter.onError(e);
            }
        }
    }).subscribeOn(Schedulers.io())
      .observeOn(AndroidSchedulers.mainThread());
}

When I rewrite this via a normal Lambda, then I get this error:

Incompatible types: Required: Observable <java.lang.String>. Found: Observable <java.lang.Object>.

This is what I tried:

public Observable<String> getUserInfo() {
    return Observable.create( emitter -> {
            try {
                emitter.onNext(getPlayerInfo();
                emitter.onComplete();
            } catch (Exception e) {
                emitter.onError(e);
            }
        }).subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}
tm1701
  • 7,307
  • 17
  • 79
  • 168
  • Possible duplicate of [Lambda Expression and generic method](https://stackoverflow.com/questions/22588518/lambda-expression-and-generic-method) – Sharon Ben Asher Nov 30 '18 at 17:06
  • Why do you *want* to, though? I see no difference in perceived readability or ceremony between the two forms. – Makoto Nov 30 '18 at 17:10
  • Lambda's not always improving the readability of the code. I agree. In this case it is more concise. Only the business logica is shown, no ceremony stuff. – tm1701 Nov 30 '18 at 17:17

2 Answers2

3

The inference engine of the compiler cannot determine the type parameter of Observable, so you need to explicitly specify it:

return Observable.<String>create( emitter -> {
Andreas
  • 154,647
  • 11
  • 152
  • 247
1

Type inference fails specifically because of the trailing calls to subscribeOn and observeOn. Another solution is introducing an intermediate method or variable, for example:

private Observable<String> getUserInfo() {
    Observable<String> userInfo = Observable.create( emitter -> {
            try {
                emitter.onNext(getPlayerInfo();
                emitter.onComplete();
            } catch (Exception e) {
                emitter.onError(e);
            }
        });

    return userInfo
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread());
}
Joni
  • 108,737
  • 14
  • 143
  • 193