先来学习概念
为了理解lambda表达式的Java实现,需要先搞懂两个结构:
1是lambda表达式自身,2是函数式接口。
1是lambda表达式自身
lambda表达式就是一个匿名方法(即未命名),这个方法不是独立执行的,是用于实现由函数式接口定义的另一个方法。因此lambda表达式会导致生成一个匿名类,lambda表达式也被成为闭包。
lambda表达式引入了新的操作符:->,有时被称之为lambda操作符,或者箭头操作符,它将lambda表达式分为两个部分:左侧和右侧。箭头左侧制定了表达式所需要的参数,右侧制定了lambda体,即表达式要执行的动作。用语言描述时,可以把->表达为“成了”或者是“进入”。
lambda体有两种,一种是只包含单独一个表达式,另外一种包含一个代码块。本文只讨论第一种。
2是函数式接口
函数式接口是指近指定了一个抽象方法的接口。就是一个接口,就只有一个方法,还是抽象的。
例如:
interface MyNumber{
double getValue();
}
lambda表达式不是独立执行的,而是构成了一个函数式接口中定义的抽象方法的实现。当把一个lambda表达式赋给一个函数式接口的引用时候,就完成了这种关联,在lambda表达式和抽象方法之间建立了联系。
例如下面的代码:
MyNumber myNum;//declare an interface reference 定义一个接口引用
//Here ,the lambda expression is simply a constant expression.
//这里,lambda表达式只是一个简单的常量表达式
//When it is assigned to myNum,a class instance is constructed in which the lambda expression
//当它分配给了myNum,一个类实例就被创建了,其中lambda表达式实现了MyNumer接口中的getValue()方法。
//implements the getValue() method in MyNumber.
myNum=()->123.45;
当目标类型上下文中出现lambda表达式时,会自动创建实现了函数式接口的一个类的实例。接口的抽象方法的行为由lambda表达式定义,当通过目标调用该方法时,会执行这个lambda表达式。因此lambda表达式提供了一种将代码片段转换为对象的方法。(我觉得这句翻译的不对,应该翻译为:lambda表达式提供了一种途径,可以将代码片段转换为对象的方法)
以下是几个lambda表达式章节的具体代码。
//Demonstrate a simple lambda expression
// A functional interface 一个函数接口
interface MyNumber{
double getValue();
}
class LamdaDemo {
public static void main(String[] args){
MyNumber myNum;//declare an interface reference 定义一个接口引用
//Here ,the lambda expression is simply a constant expression.
//这里,lambda表达式只是一个简单的常量表达式
//When it is assigned to myNum,a class instance is constructed in which the lambda expression
//当它分配给了myNum,一个类实例就被创建了,其中lambda表达式实现了MyNumer接口中的getValue()方法。
//implements the getValue() method in MyNumber.
myNum=()->123.45;
//Call getValue(),which is provided by the previously assigned lambda expression
//调用 getValue(),它由之前分配的lambda表达式提供
System.out.println("A fixed value:"+myNum.getValue());
// here a more complex expression is uesed.一个更复杂的表达式
myNum=()->Math.random()*100;
//These call the lambda expression in the previous line.
System.out.println("A Random value:"+myNum.getValue());
System.out.println("Another Random value:"+myNum.getValue());
System.out.println("Third Random value:"+myNum.getValue());
System.out.println("Fourth Random value:"+myNum.getValue());
System.out.println("Fifth Random value:"+myNum.getValue());
// A lambda expression must be compatible with the method defined by the functional interface.
//so,this will not work
//myNum=()->"123.45";//error
}
}
运行以上代码,执行结果如下:
A fixed value:123.45
A Random value:61.66538013500148
Another Random value:17.333396843025263
Third Random value:7.084136555354059
Fourth Random value:25.68092767959763
Fifth Random value:30.843937118381724
你会发现,运行一次myNum.getValue(),这个得到的值每次都不一样。可以理解为每次运行getValue(),都运行了一次lambda表达式:Math.random()*100;
Math.random()默认产生大于等于0.0且小于1.0之间的随机double型随机数,再乘以100.这就是程序能出这个结果的原因。