Lambda return value in java

So far I have been able to find all the answers that I need, but this is confusing for me. Say we have an example code:

public class Animal { private String species; private boolean canHop; private boolean canSwim; public Animal(String speciesName, boolean hopper, boolean swimmer) { species = speciesName; canHop = hopper; canSwim = swimmer; } public boolean canHop() { return canHop; } public boolean canSwim() { return canSwim; } public String toString() { return species; } } public interface CheckAnimal { public boolean test(Animal a); } public class FindSameAnimals { private static void print(Animal animal, CheckAnimal trait) { if(trait.test(animal)){ System.out.println(animal); } public static void main(String[] args) { print(new Animal("fish", false, true), a -> a.canHop()); } } 

The OCA study guide (Exam 1Z0-808) says these two lines are equivalent:

 a -> a.canHop() (Animal a) -> { return a.canHop(); } 

Does this mean that behind the scenes Java adds the return keyword to the code in the first case?

If the answer is “YES”, then how the following code compiles (imagine that everything else is in the right place):

 static int counter = 0; ExecutorService service = Executors.newSingleThreadExecutor(); service.execute(() -> counter++)); 

if we know what signatures to run and runnable run:

 void execute(Runnable command) void run() 

If the answer is NO, how does Java know when it needs to return something, and when not? Maybe in

 a -> a.canHop() 

we wanted to ignore the boolean type of the return method.

+6
source share
3 answers

Does this mean that behind the scenes Java adds a keyword to the code in the first case?

Not. The compiler generates bytecode and can generate the same bytecode, but it does not change the syntax and then compiles it again.

we wanted to ignore the boolean type of the return method.

It has the ability to ignore a value based on which functional interfaces it considers.

 a -> a.canHop() 

may be

 (Animal a) -> { return a.canHop(); } 

or

 (Animal a) -> { a.canHop(); } 

depending on the context, however, if possible, he endorses the former.

Consider ExecutorService.submit(Callable<T>) and ExecutorService.submit(Runnable)

 ExecutorService es = Executors.newSingleThreadExecutor(); es.execute(() -> counter++); // has to be Runnable es.submit(() -> counter++); // Callable<Integer> or Runnable? 

Keeping the return type, you can see its Callable<Integer>

 final Future<Integer> submit = es.submit(() -> counter++); 

To try yourself, here is a long example.

 static int counter = 0; public static void main(String[] args) throws ExecutionException, InterruptedException { ExecutorService es = Executors.newSingleThreadExecutor(); // execute only takes Runnable es.execute(() -> counter++); // force the lambda to be Runnable final Future<?> submit = es.submit((Runnable) () -> counter++); System.out.println(submit.get()); // returns a value so it a Callable<Integer> final Future<Integer> submit2 = es.submit(() -> counter++); System.out.println(submit2.get()); // returns nothing so it must be Runnable final Future<?> submit3 = es.submit(() -> System.out.println("counter: " + counter)); System.out.println(submit3.get()); es.shutdown(); } 

prints

 null 2 counter: 3 null 

The first submit accepts a Runnable , so Future.get() returns null

The second submit defaults to Callable , so Future.get() returns 2

The third submit can only be the void return value, so it must be Runnable , so Future.get() returns null

+9
source

Yes, if you specify only one operator, its value is automatically returned from lambda.

Then, since Runnable is a functional interface, it can be defined as a lambda. The return type is void , so any return value inside the lambda will be ignored.

+3
source

You get confused about the scope of the return . The return (inserted as bytecode by the compiler or as source code by the programmer) is returned from the lambda, not from the method that calls the lambda.

 void foo() { Supplier<String> s = () -> { return "bar" }; String s = s.get(); // s is assigned to "bar" // Execution continues as the return statement in the lambda only returns from the lambda and not the enclosing method System.out.println("This will print"); } 
0
source

All Articles