Lambda表达式是用最少的句法来完成方法定义。在Java虚拟机上,所有的东西都是一个类,在背后有很多操作,让lambda表达式看起来像方法。但是在虚拟机上应该还是一个类!
interface Description{
String brief();
}
interface Body{
String detailed(String head);
}
interface Multi{
String twoArg(String head, Double d);
}
public class LambdaExpressions {
static Body bod = h -> h + "no parens!";
static Body bod2 = (h) -> h + "more details";
static Multi mult = (h, n) -> h+n;
static Description desc = () -> "short info";
static Description moreLines = () -> {
System.out.println("more lines()");
return "from more lines()";
};
public static void main(String[] args) {
System.out.println(bod.detailed("OH"));
System.out.println(bod2.detailed("HI!"));
System.out.println(desc.brief());
System.out.println(mult.twoArg("PI", 3.14));
System.out.println(moreLines.brief());
}
}
解析:
我们有三个接口:都是函数式接口(只有一个需要被实现的方法)每一个接口里面的都有不同数量的参数需要被传入。
基本概念:
1. 入参
2. -> 的意思是produce,入参在左边
3. 右边是函数体
【1】bod,因为只有一个参数没有括号
【2】bod2,常规操作,入参有一个括号
【3】 desc,没有入参,还是要括号
【4】 mult 如果超过一个参数,那么把参数方法括号里
【5】如果超过一行,那么就要用{}包裹,还要有返回值
递归:
递归方法是一个自己call自己的方法,使用lambda表达式也可以写递归。但是必须满足一个条件,就是那个方法必须作为成员变量或者静态变量,不然会有编译错误。我们会写两个例子
类的静态变量:
interface IntCall{ int call (int arg); } public class RecursiveFactorial { static IntCall fact; public static void main(String[] args) { fact = n -> n == 0 ? 1 : n * fact.call(n - 1); for (int i = 0; i <= 10; i++) { System.out.println(fact.call(i)); } } }
成员变量
interface A { int call(int i); } public class RecursiveFibonacci { A caller; public RecursiveFibonacci() { this.caller = i -> { if (i == 0) { return 0; } else if (i == 1) { return 1; } else { return caller.call(i - 1) + caller.call(i - 2); } }; } public static void main(String[] args) { RecursiveFibonacci rec = new RecursiveFibonacci(); for (int i = 0; i <= 10; i++) { System.out.println(rec.caller.call(i)); } } }
方法引用
类/对象名::方法名
interface Callable{
void call (String s);
}
class Describe{
void show(String msg){
System.out.println(msg);
}
}
public class MethodReferences {
static void hello(String name){
System.out.println("hello, " + name);
}
static class Description{
String about;
Description (String desc){
about = desc;
}
void help(String msg){
System.out.println(about + " " + msg);
}
}
static class Helper{
static void assist(String msg){
System.out.println(msg);
}
}
public static void main(String[] args) {
Describe d = new Describe();
Callable c = d::show; //对象引用
c.call("call()");
c = MethodReferences::hello; //静态方法
c.call("Bob");
c = new Description("valuable")::help; //对象引用
c.call("information");
c = Helper::assist; //静态方法
c.call("Help!");
}
}
综合比较:
class Go{
static void go(){
System.out.println("GO::go()");
}
}
public class RunableMethodReference {
public static void main(String[] args) {
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("anonymous");
}
}).start();
new Thread(()-> System.out.println("lambda")).start();
new Thread(Go::go).start();
}
}