根据百度介绍:
Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式可以表示闭包(注意和数学传统意义上的不同)。
从介绍来看,Lamdba表达式是一个闭包的匿名函数
Parameters -> an expression
这是lambda的基本表示形式,箭头前的为参数,箭头后的为方法表达式
若在方法表达式中,有多个语句要执行的话,要使用{}将表达式括起来,然后使用->将两端连接起来,意为将参数传递给方法体
Parameters -> {many expressions} ;
Lambda表达式有以下的重要特征
首先我们先创建一个接口,其中包含一个没有参数的方法
public interface Speaker {
void speak();
}
接下来,我们使用Lambda来对此方法进行功能的实现,invoke方法是用来执行匿名内部类中的方法的
public class Main {
public static void main(String[] args) {
invoke(() -> {
System.out.println("asd");
});
}
public static void invoke(Speaker speaker){
speaker.speak();
}
}
打印输出如下
asd
在这里,我们使用stream流对list进行了筛选,其中e
就是我们传入的参数。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
List<Integer> collect = list.stream().filter(e -> e < 5).collect(Collectors.toList());
collect.forEach(e-> System.out.println(e));
函数式接口时JDK 1.8中新增的一个接口,这个接口的作用是实现函数式接口的类可以被隐式转换成lambda表达式
创建Man接口,实现加上@FunctionInterface
@FunctionalInterface
interface Man{
void speak(String str);
}
使用lambda的方式创建实现Man接口的实例
Man man = str -> System.out.println(str);
man.speak("Hello");
在FunctionInterface的源码中特殊说明了在函数式接口中只能由一个唯一的抽象方法Conceptually, a functional interface has exactly one abstract method.
,但是也有一种例外的情况能拥有多种方法,就是这些方法要是在Object类型中已有的,例如:
@FunctionalInterface
interface Man{
void speak(String str);
boolean equals(Object man);
}
但是其他的方法不能够由lambda表达式去实现方法,因为他已经被其他类给实现了Conceptually, a functional interface has exactly one abstract method. Since default methods have an implementation, they are not abstract. If an interface declares an abstract method overriding one of the public methods of java.lang.Object, that also does not count toward the interface's abstract method count since any implementation of the interface will have an implementation from java.lang.Object or elsewhere.
此外,函数式接口中的方法可以有默认的实现方式,就是在方法名前加入default关键词
要注意的是,默认的方法不算在函数式接口的方法中,所以你除了实现默认方法外,还要在实现一个方法
@FunctionalInterface
interface Man{
default void defaultspeak(String str) {
System.out.println("I will speak:"+"\""+str+"\"");
}
void speak(String str);
}
调用默认方法
Man man = str -> System.out.println(str);
man.defaultspeak("hello");
man.speak("Hello");
除了使用Lambda表达式和函数式接口来为一个接口的实现类来实现方法以外,我们还可以通过方法引用的方法来将已有的方法
传递给接口来创建实体类
例如:我们创建一个数字比较类,其中有一个方法为比较两数,返回最大值。
public class NumberComparetor {
public static int compareMax(int i , int j){
return i>j?i:j;
}
}
自定义一个比较器
public interface MyComparetor<T> {
Object compare(int x, int y);
}
我们使用方法引用的方式来实现MyComparetor接口,将NumberComparetor传递给它,然后比较两数字大小并输出
public void test(){
MyComparetor myComparetor = NumberComparetor::compareMax;
System.out.println(myComparetor.compare(1,2));
System.out.println();
}
输出结果为
2