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);
}
}
任何人都可以帮我理解这个吗?我的印象是,只有当我们实现一个接口并覆盖它的方法(用Lambda表达式替换Anonymous类)时,我们才能在Java 8中使用lamba表达式。
同样在哪种情况下调用方法invoke(Runnable r)
?
答案 0 :(得分:8)
在以下一行
String s = (String) invoke(() -> true);
实际上invoke(Callable)
被调用了。原因是:
() -> true
是一个lambda表达式,它具有零形式参数并返回结果。call()
接口的功能方法Callable
兼容。请注意,接口不需要@FunctionalInterface
注释,只需要一个抽象方法。如果要改为调用invoke(Runnable)
,则需要创建一个与函数方法兼容的lambda,该函数方法采用零参数并且不返回任何结果(即符合run()
的签名) 。像这样:
invoke(() -> System.out.println("foo"));
在跑步时只打印foo
。
答案 1 :(得分:8)
lambda表达式提供了功能接口的实现。这就是您的代码段所做的事情。
您对invoke
的调用传递的lambda表达式没有返回值的参数(在您的情况下为boolean
)。因此,它与Object invoke(Callable c)
匹配,而不是void invoke(Runnable r)
(因为Callable
call
方法具有返回值,而Runnable
' s run
方法不会返回任何内容。
invoke(() -> {System.out.println("something");});
将调用void invoke(Runnable r)
,因为在这种情况下,lambda表达式没有返回类型。
答案 2 :(得分:7)
仅当我们实现接口并覆盖其方法时
这或多或少都是你在这里所做的。不是方法 s ,而只是一种方法:() -> true
。这个Callable#call()
部分是您String s = (String) invoke(() -> true);
的实现。
换句话说,这一行:
String s = (String) invoke(new Callable() {
@Override
public Object call() throws Exception {
return true;
}
});
完全等同于这个:
#server.R
library(shiny)
library(ggplot2)
shinyServer(function(input, output, session) {
numberInput <- reactive({
input$checkbox
})
lapply(1:10, function(i) {
output[[paste0('b', i)]] <- renderPlot({
qplot(x = rnorm(100, mean = as.numeric(numberInput()[i]))) +
ggtitle(paste("This plot was plotted with", numberInput()[i], "option"))
})
})
})
#ui.R
library(shiny)
shinyUI(fluidPage(
title = 'lapply example',
sidebarLayout(
sidebarPanel(
checkboxGroupInput("checkbox", "Checkbox",
choices = sample(1:10, 5))
),
mainPanel(
lapply(1:10, function(i) {
plotOutput(paste0('b', i))
})
)
)
))
答案 3 :(得分:0)
Lambda表达式是编写匿名类实例的另一种方法,使匿名类的实例更容易编写。在JVM中,与使用new
创建普通java对象(执行静态变量,静态块,从整个层次结构中加载类)相比,它不会占用太多内存。
Lambda表达式语法:
(params) -> expression to implement a @FunctionalInterface
在您的测试用例中:String s = (String) invoke(() -> true);
表达式的返回类型true
没有参数。因此Runnable
FunctionalInterface
与lambda表达式不匹配,因为它具有void run()
属性。它使用
与Callable
FuncationalInterface
匹配
V call()
。
lambda表达式如何在幕后工作?
看起来lambda表达式可能只是匿名内部类的语法糖,但是有更优雅的方法。最简单的解释是: lambda表达式由一个新方法表示,并在运行时使用invokedynamic调用。
源代码:
class LambdaExample {
public void abc() {
Runnable r = () -> {
System.out.println("hello");
}
r.run();
}
}
等效的字节码:
class LambdaExample {
public void abc() {
Runnable r = <lambda$1 as Runnable instance>;
r.run();
}
static void lambda$1() {
System.out.println("hello");
}
}
在JVM中,有一个lambda工厂,它从生成的lambda方法(例如lambda $ 1)创建一个功能接口的实例(例如Runnable)。
Lambda表达式很棒,Java 8...
中有更多优秀的东西答案 4 :(得分:0)
看看下面的例子。
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);
}
}