基本形式
(str)->{
System.out.println(str)
};
调用作为参数的接口实例的方法
1、用一个类实现接口,然后使用该类实例调用方法
2、匿名内部类
3、在 接口(不能是抽象类) 有且只有一个抽象方法时,可以使用lamda表达式来重写这个方法,JAVA会自动生成一个对应的匿名实现类
ps.有且只有一个抽象方法的接口称为函数式接口
参数类型可以省略,JVM会自己去接口里根据方法声明确定类型
public class Main {
public static void main(String[] args) throws IOException {
useEatable((how)->{
System.out.println(how);
return true;
});
}
private static void useEatable(Eatable e){
boolean success = e.eat("我吃了很多");
System.out.println(success);
}
}
interface Eatable{
public boolean eat(String how);
}
也可以直接用lambda表达式直接造一个匿名的接口实现类的实例
Eatable e = (how)->{
System.out.println(how);
return true;
};
lambda表达式和匿名内部类的区别
- 匿名内部类可以作为具体类、抽象类或接口的子类实例
- lambda表达式只能做接口的匿名实现类实例
- 函数式接口可以使用lambda表达式或匿名内部类,如果有多个抽象方法只能用匿名内部类
方法引用
函数式接口的匿名实现非要用lambda表达式或者匿名内部类吗?它们真的很冗余
如果有已经存在的方法可以实现重写方法的功能时,可以直接用方法引用
方法引用符 ::
useEatable(s->System.out.println(s));
简化成
useEatable(System.out::println);
jvm把引用当方法实现作为重写方法的实现并且创建一个匿名的函数式接口实现类实例,参数信息它自己推导
引用类静态方法
Integer::parseInt
引用特定对象的方法
"Hello World"::toUpperCase
引用类的任意对象的方法
useMyString((s,start,end)->s.substring(x,y));
等同于
useMyString(String::substring);
lambda表达式的第一个参数视为调用方法的实例,后面的参数都是输入方法的参数
引用构造器
String::new