相关概念
函数式接口:只包含一个抽象方法声明的接口。
Lambda表达式:可理解为一种匿名函数,它不属于一个特定的类,但是却有参数列表、函数主体、返回类型、异常列表,可以作为参数传递给方法、或者存储在变量中。
基本语法
(parameters...) -> expression 或 (parameters...) -> { statements; }
<!--parameters:参数-->
<!--expression:表达式-->
<!--statements:语句-->
->符左边为参数列表,右边为Lambda体;具体语法举例如下:
| - | - |
|---|---|
| 无参数,无返回值 | ()->{} |
| 无参数,有返回值 | ()->"0" |
| 有参数,无返回值 | (x)->System.out.print(x) 或 (x)->{System.out.print(x);} |
| 有参数,有返回值 | (x)->x+1 或 (x)->{return x+1;} |
Lambda表达式使用
每个 Lambda 表达式都能隐式地赋值给函数式接口;
例如:在 Runnable 接口中只声明了一个方法 void run(),我们可以通过 Lambda 表达式创建 Runnable 接口的引用。
先回顾一下不使用Lambda表达式开辟一个新线程的方法:
public class LambdaTest {
public static void main(String [] args){
Runnable runnable = new Runnable() {
@Override
public void run() {
System.out.println("run111");
}
};
new Thread(runnable).start();
}
}
以上代码通过内部类的方式来创建Runable接口实例,实际上代码已经很简洁了,再来看下Lambda表达式实现:
public class LambdaTest {
public static void main(String [] args){
Runnable runnable = ()->System.out.println("run111");
new Thread(runnable).start();
// 当不指明函数式接口时,编译器会自动解释这种转化
// new Thread(()->System.out.println("run111")).start();
}
}
以上两种方式运行结果均为"run111"
实际上:每个Lambda表达式均返回一个函数式接口的实例化对象
自定义函数式接口
@FunctionalInterface注解是jdk8新加入的一种接口,用于指明该接口类型声明是根据 Java 语言规范定义的函数式接口。
@FunctionalInterface
public interface TestInterface { //定义一个函数式接口
void doSomething();//无参数,无返回值
}
@FunctionalInterface
public interface ParamInterface { //定义一个函数式接口
Integer doSomething(Integer i);//有参数,有返回值
}
public class Test {
public static void test(TestInterface t) {
t.doSomething();
}
public static void main(String [] args) {
//内部类调用
test(new TestInterface() {
@Override
public void doSomething() {
System.out.println("内部类");
}
});
//Lambda表达式调用
test(() -> System.out.println("Lambda"));
//有参数,有返回值调用
ParamInterface p = (Integer i) -> {
int j = i+1;
return j;
};
System.out.println(p.doSomething(10));
}
}
打印结果为:
内部类
Lambda
11