0

I keep getting expression can be replaced with a lambda for Java 8. How do I go about that? Here's one of the expressions I get that message on:

Observable.create(new ObservableOnSubscribe<Pair>() {
            @Override
            public void subscribe(@io.reactivex.annotations.NonNull ObservableEmitter<Pair> observableEmitter) throws Exception { ...

any idea?

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
  • Honest question- why do you care? The two are exactly equivalent. A lambda and an anonymous class compile into the same bytecode. There is no technical reason to use one over the other. I'd just turn off that lint, its someone putting his personal preferences into the default. – Gabe Sechan Nov 14 '17 at 21:48
  • 2
    @GabeSechan they are not the same. `this` is different for them; potentially less objects would be created in case of lambda - one per Call-Site; one is created via `invokedynamic` *at runtime*, the other is not, and there are more differences – Eugene Nov 14 '17 at 22:30
  • @Eugene Everything I've read and seen show the same bytecode. At this point, you'd need to show extensive evidence otherwise. Even then I don't think you could convince me that its worth converting existing code for the minor differences you mention. – Gabe Sechan Nov 14 '17 at 22:33
  • 2
    @GabeSechan first, my comment was put *not* to convince you in any way; it is solely to show that there is a difference - significant for some and apparently not so much for others. – Eugene Nov 14 '17 at 22:36
  • @Eugene I'd still like proof that there is one- as I said, everything I've read said the bytecode output is equivalent. – Gabe Sechan Nov 14 '17 at 22:37
  • 2
    @GabeSechan one compiled by me: https://pastebin.com/n2C0VE5i and https://stackoverflow.com/questions/27524445/does-a-lambda-expression-create-an-object-on-the-heap-every-time-its-executed and https://stackoverflow.com/questions/16827262/how-will-java-lambda-functions-be-compiled – Eugene Nov 14 '17 at 22:43
  • 2
    @GabeSechan as a side note, `invokedynamic` *is* (string concatenation in java-9) used and will be exploited and used even further in jdk-10. – Eugene Nov 14 '17 at 22:45
  • @Eugene ok, I buy your proof. I'm not particularly concerned about Java 9 or 10 for Android though- we just got Java 8 as a fully supported language, and due to lawsuits with Oracle I wouldn't be surprised to never see an update again. – Gabe Sechan Nov 14 '17 at 22:56
  • 2
    @GabeSechan IMO you are deviating from the subject... But lets stop here: there is a diff and *might* be significant for some – Eugene Nov 14 '17 at 22:58

2 Answers2

2

Due to the fact that any interface which has a SAM is by nature a functional interface, we can, therefore, do something like this:

Observable.create(e -> { /* do logic */ });

Note, that the above approach does not bubble up exceptions if any occur within the scope of create. To accomplish such behavior with lambdas (anonymous functions) you can create a wrapper method and perform the logic there i.e:

public void subscribeWrapper(ObservableEmitter<Pair> e) throws java.lang.Exception {
    // do logic
}

then you'd do:

Observable.create(e -> subscribeWrapper(e));

On the other hand, you could ignore creating the said method and use a try/catch within the lambda statement block and rethrow the exception from there.

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
1

This is how a lambda for this is created:

observableEmitter -> {
    // your code here
}

You don't need the anonymous function or anything like that.

Putting it in the given code:

Observable.create(observableEmitter -> {
    // your code here
});

You just replace the new ObservableOnSubs... bit with the lambda.

  • it asks to replace new ObservableOnSubscribe(), where does the subscribe code go? can you explain with respect to my code? –  Nov 14 '17 at 21:37
  • Edited my answer, clarifying your question. –  Nov 14 '17 at 21:41
  • Also I would like to add: option + enter (on mac), automatically replaces expression with lambda expressions. –  Nov 15 '17 at 14:57