6

For example:

private String test(Optional myOptional)
{
    myOptional.ifPresent(() -> return "1");
    return "0";
}

so when I call test(myOptional) it will return "1";

newacct
  • 119,665
  • 29
  • 163
  • 224
user2620644
  • 521
  • 1
  • 12
  • 25

2 Answers2

9

You can't "break" out of the lambda body and return a value from the enclosing method. The return used in the lambda works only in the scope of the lambda body.

The idiomatic way would be to levarage Optional API properly:

private String test(Optional<Object> myOptional) {
    return myOptional
      .map(s -> "1")
      .orElse("0");
}

Also, keep in mind that Optionals should not be used as a method argument:

Why should Java 8's Optional not be used in arguments

Grzegorz Piwowarek
  • 13,172
  • 8
  • 62
  • 93
  • 1
    Good answer. Better than mine. I'd change the function to definition to: `private String test(Optional myOptional)` – Michael Aug 03 '17 at 12:59
  • @Michael hard to say what was the OP's intention here but surely it's one of the valid options – Grzegorz Piwowarek Aug 03 '17 at 13:00
  • Perfect answer, thank you! But it's not possible to break the method's execution just to avoit next method instructions to execute, right? – user2620644 Aug 04 '17 at 13:57
1

The issue you're having is that the return is taken as the return of the lambda function, not the return of the 'test' function.

Optional.ifPresent is not expecting to be given a function that returns a value. It expects a Consumer<T> which is effectively a function which takes exactly one parameter and returns nothing. As a normal function, rather than a lambda it would look something like this:

void myConsumer(String s)
{
    System.out.println(s);
}

You probably want to use isPresent ('is' not 'if'):

if (myOptional.isPresent())
{
     return "1";
}
else
{
     return "0";
}

or using a ternary operator:

return myOptional.isPresent() ? "1" : "0";

As an aside, you are using the raw type of Optional. This will result in a compiler warning. You should declare what type the Optional will hold by using generics:

Optional<String> myOptional = /*something*/;

This will give you compile-time type safety that the Optional won't hold values other than strings.

Michael
  • 41,989
  • 11
  • 82
  • 128