1、Java函数式接口
有且仅有一个抽象方法的接口叫做函数式接口。
- 一般函数式接口都会加上
@Functionallnterface
注解,用于在编译层面确定一个接口是否是函数式接口,当然该注解是可选的,只要一个接口符合函数式接口的定义就是函数式接口,一般建议加上该注解。 - 当方法的参数是一个函数式接口式,可以使用Lambda表达式来传入该接口的一个具体实现(Java8之前采用匿名内部类来实现),来简化我们的操作。
2、Lambda表达式基本运用
Lambda 允许把函数作为一个方法的参数。
1、Lamda表达式的代码块只有一句,可省略花括号
@Functionallnterface
public interface Displayer {
//函数式接口的方法无参
void show();
}
...
public class LambdaDm {
//定义一个以接口为参数的方法
public void show(Displayer d) {
d.show();
}
public static void main(String[] args) {
//Lamda表达式的代码块只有一句,省略了花括号
LambdaDm.show(() -> System.out.println("少儿频道"));
}
}
2、只有一个参数时,可以省略圆括号
public interface Displayer {
//函数式接口的方法只有一个参数
void show(int n);
}
...
public class LambdaDm {
//定义一个以接口为参数的方法
public void show(Displayer d) {
d.show(14);
}
public static void main(String[] args) {
//只有一个参数时,可以省略圆括号
LambdaDm.show(n -> {
System.out.println("你当前收看的是CCTV-"+n);
System.out.println("少儿频道");
});
}
}
3、lambda只有一条语句,可以省略return
public interface Displayer {
int show(int a, int b);
}
...
public class LambdaDm {
//定义一个以接口为参数的方法
public void show(int a, int b) {
System.out.printf("%d + %d = %d\n", a, b, show(a, b));
}
public static void main(String[] args) {
//lambda只有一条语句,可以省略return
LambdaDm.show((a, b) -> {
a + b;
});
}
}
3、Lambda表达式方法引用与构造器引用
函数式接口的实例可以通过 lambda 表达式、 方法引用、构造方法引用来创建。如果Lambda表达式的代码块只有一条代码,还可以使用方法引用与构造器引用。
@FunctionalInterface
public interface Converter {
Integer convert(String from);
}
1、引用类方法
类名 :: 实例方法名
public static void main(String[] args) {
//1.引用类方法
//使用Lamba表达式创建Convert对象
Converter converter1 = from -> Integer.valueOf(from);
Integer val = converter1.convert("99");
//函数式接口中被实现方法的全部参数传给该类方法作为参数
Converter converter2 = Integer::valueOf;
Integer val2 = converter2.convert("100");
}
2、使用特定对象的实例方法
对象名(引用名) :: 实例方法名
public static void main(String[] args) {
//2.使用特定对象的实例方法
Converter converter3 = from -> "特定对象".indexOf(from);
Integer val3 = converter3.convert("对");
Converter converter4 = "特定对象"::indexOf;
Integer val4 = converter4.convert("象");
}
3、引用某类对象的实例方法
@FunctionalInterface
public interface MyTest {
String test(String a, int b, int c);
}
...
public static void main(String[] args) {
//3.引用某类对象的实例方法
MyTest myTest = (a, b, c) -> a.substring(b, c);
String val5 = myTest.test("引用类对象实例方法", 1, 5);
//第一个参数作为调用者,后面的参数全部传给该方法作为参数
MyTest myTest2 = String::substring;
String val6 = myTest2.test("引用类对象实例方法", 1, 5);
}
4、引用构造器
类名 :: new
@FunctionalInterface
public interface YourTest {
// 抽象方法负责根据 String 参数生成一个 JFrame 返回值
JFrame win(String title);
}
...
public static void main(String[] args) {
//4.引用构造器
YourTest yourTest = title -> new JFrame(title);
yourTest.win("窗口");
//函数式接口中被实现方法的全部参数传给该构造器作为参数
YourTest yourTest2 = JFrame::new;
yourTest2.win("窗口2");
}