Lambda expressions in Java8

import java.util.concurrent.Callable; public class AdvancedLambda { static void invoke(Runnable r){ r.run(); } static Object invoke(Callable c) throws Exception { return c.call(); } public static void main(String[] args) throws Exception { String s = (String) invoke(() -> true); System.out.println(s); } } 

Can someone help me figure this out? I got the impression that we can use lamba expressions in Java 8 only when we implement the interface and override its methods (replacing anonymous classes with Lambda expressions).

Also, in what situation will the invoke(Runnable r) method be called?

+7
java lambda java-8
source share
5 answers

In the next line

 String s = (String) invoke(() -> true); 

Actually invoke(Callable) is called. The reason is that:

  • () -> true is a lambda expression that has a null formal parameter and returns a result.
  • Such a signature (null parameter, the only result) is compatible with the call() Callable functional method. Note that the interface does not require the @FunctionalInterface annotation, it just needs to have one abstract method.

If you want to invoke(Runnable) instead, you will need to create a lambda that is compatible with a function method that takes a null parameter and returns no result (i.e., it matches the run() signature). Something like that:

 invoke(() -> System.out.println("foo")); 

That just prints foo at startup.

+7
source share

The lambda expression provides an implementation for a functional interface. This is what your code snippet does.

Your invoke call passes a lambda expression with no arguments that return a value (a boolean in your case). Therefore, it corresponds to Object invoke(Callable c) , and not void invoke(Runnable r) (since the Callable call method has a return value, and the Runnable run method returns nothing).

 invoke(() -> {System.out.println("something");}); 

will call void invoke(Runnable r) , since in this case the lambda expression has no return type.

+7
source share

only when we implement the interface and redefine its methods

This is more or less what you are doing here. Not the s method, but only one method: call() . This part () -> true is your implementation of Callable#call() .

In other words, this line:

 String s = (String) invoke(() -> true); 

will be fully equivalent to this:

 String s = (String) invoke(new Callable() { @Override public Object call() throws Exception { return true; } }); 
+5
source share

Lambda expression is another way to write an instance of an anonymous class to make an anonymous class instance easier to write. In the JVM, it will not take up much memory compared to the usual creation of Java objects using new (execution of static variables, static blocks, loading classes from a single hierarchy).

enter image description here

Lambda expression syntax:

 (params) -> expression to implement a @FunctionalInterface 

In your test case: String s = (String) invoke(() -> true); the expression has a return type of true with no argument. Thus, Runnable FunctionalInterface does not match the lambda expression because it has the void run() attribute. It matches Callable FuncationalInterface using V call() .

How do lambda expressions work under the hood?
It may seem that lambda expressions are just syntactic sugar for anonymous inner classes, but there is a much more elegant approach. The simplest explanation: the lambda expression is represented by a new method and is invoked at run time using invokedynamic.

Source:

 class LambdaExample { public void abc() { Runnable r = () -> { System.out.println("hello"); } r.run(); } } 

Bytecode equivalent:

 class LambdaExample { public void abc() { Runnable r = <lambda$1 as Runnable instance>; r.run(); } static void lambda$1() { System.out.println("hello"); } } 

Inside the JVM, there is a lambda factory that creates an instance of a functional interface (e.g. Runnable) from the generated lambda method (e.g. lambda $ 1).

Lambda expressions are great, and in Java 8 ...

0
source share

Take a look at the example below.

 import javafx.beans.DefaultProperty; import jdk.nashorn.internal.codegen.CompilerConstants; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; /** * Created by KUMAJYE on 13/09/2016. */ public class ThreadMonitor { private static int noOfThreads = 0; public static void main(String[] args) { ThreadModel threadModel; noOfThreads = Integer.parseInt(args[0]); if (noOfThreads > 0) { threadModel = getThreadingModelForCallsInCallingThread(); } else { threadModel = getAsynchThreadingModel(); } } public static ThreadModel getThreadingModelForCallsInCallingThread() { ExecutorService executor = Executors.newFixedThreadPool(noOfThreads); return (r) -> executor.submit(r); } public static ThreadModel getAsynchThreadingModel() { // do execution on same Thread or separate Thread. // or // r.run(); return (r) -> new Thread(r).start(); } interface ThreadModel { void invoke(Runnable r); } 

}

0
source share

All Articles