Lambda表达式就是函数式思想
一、Lambda
1.体验Lambda表达式
public class Lambda {
public static void main(String[] args) {
//实现类的方式实现需求
MyRunnable my = new MyRunnable();
Thread t = new Thread(my);
t.start();
//匿名内部类
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("Lambda");
}
}).start();
//Lambda表达式
new Thread(() -> {
System.out.println("Lambda");
}).start();
}
}
2.Lambda表达式的标准格式
():里面没有内容相当于方法的形式参数为空
->:用箭头指向后面要做的事情
{}:包含一段代码,我们称之为代码块就是方法体中的内容
()->{}
3.Lambda表达式的练习
Lambda表达式的使用前提
·有一个接口
·接口中有且仅有一个抽象方法
特点
·Lambda表达式没有命名,用来像传递数据一样的传递操作
·函数接口里面只有一个抽象方法,被当作Lambda表达式的类型,最好使用@FunctionalInterface注解,防止其他人往里面添加方法
练习1:
定义一个接口(Eatable),里面定义一个抽象方法:void eat()
定义一个测试类(EatableDemo),在测试类中提供两个方法
一个主方法
一个UseEatable(Eatable e)
//接口
public interface Eatable {
void eat();
}
//类
public class EatableDemo {
public static void main(String[] args) {
useEatable(()->{
System.out.println("eat方法...");
});
}
public static void useEatable(Eatable e){
e.eat();
}
}
4.Lambda表达式的省略模式
参数的类型可以省略,有多个情况下,不能只省略一个
如果参数有且只有一个,那么小括号可以省略
如果代码块的语句只有一条,可以省略大括号和分号(如果有return,return 也要省略)
5.Lambda表达式的注意事项
使用Lambda,必须有上下文环境,才能推导出Lambda对应的接口
·局部变量赋值
·调用方法的参数
6.匿名内部类与Lambda表达式的区别
匿内部类
·接口、抽象类、具体类
·可以有多个方法
·会生成字节码文件
Lambda
·接口
·接口中只能有一个方法
·动态生成,不会产生字节码文件
public class EatableDemo {
public static void main(String[] args) {
String []arr={
"this","that","sear"
};
List<String> strings = Arrays.asList(arr);
strings.forEach(p-> System.out.println(p));
strings.forEach(System.out::println);
}
}
二、函数式接口
1.什么是函数式接口
只包含一个抽象方法的接口,称为函数式接口。
可以通过Lambda表达式创建该接口的对象
可以在一个接口上使用@FunctionalInterface注解,这样做可以检查它是否是一个函数式接口。同时Javadoc也会包含一条声明,说明这个接口是函数式接口
2.Java内置四大核心函数式接口
函数式接口 | 参数类型 | 返回类型 | 用途 |
---|---|---|---|
Consumer 消费型接口 | T | void | 对类型为T的对象应用操作,包含方法void accept(T t) |
Supplier 供给型接口 | 无 | T | 返回类型为T的对象,包含方法 T get() |
Function<T,R>函数性接口 | T | R | 对类型为T的对象应用操作并返回R类型结果,包含方法 R apply(T t) |
Predicate 断定型接口 | T | boolean | 确定类型为T的对象是否满足某约束,并返回boolean值。包含方法boolean test(T t) |
三、方法引用
1.什么是方法引用
当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用
方法引用可以看作是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖
2.方法引用的使用
要求:实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致
格式:使用操作符 ” :: “将类(或对象)与方法名分隔开
如下三种主要使用情况:
对象 :: 实例方法名
类 :: 静态方法名
类 :: 实例方法名