一、lambda表达式的引入
lambda表达式是JDK8新增的功能,它显著的增强了Java,原因有两点:1.增加了语法元素,使Java语言的表达能力得到提升,并流线化了一些常用方法的实现方式。2.导致API库中增加了新的功能,包括利用多核环境的并行处理功能变得更加容易,以及支持数据执行管道操作的新的流API。
lambda表达式的引入也催生了新的Java功能,包括默认方法和方法引用。默认方法允许定义接口方法的默认行为,而方法引用允许引用而不执行方法。
总之,lambda表达式的引入将影响到几乎所有的Java程序员。
二、简介
lambda表达式本质上就是一个匿名(未命名)方法。但是这个方法不是独立执行,而是用于实现函数时接口定义的另一个方法。因此会产生一个匿名类,lambda表达式也常被称为闭包。
函数式接口是仅包含一个抽象方法的接口。一般来说,这个方法指明了接口的用途,因此函数式接口通常表示单个动作。函数式接口定义了lambda表达式的目标类型。lambda表达式 只能作用于目表类型被定义的上下文中。
1.lambda表达式
操作符:->
表达式:参数->动作
例子:->122.2 相当于 double meth(){ return 122.2 }
(n)->(n%2)==0 如果n为偶数,结果为true
2.函数式接口
从JKDK8开始,可以为接口声名的方法之定默认行为,即所谓的默认方法。只有当没有指定默认方法时,接口方法才是抽象方法。
例子:
interface myNumber{
double getvalue();
}
其中 getvalue()是隐式抽象方法,并且是myNamber的位于方法。因此,myNambe是函数式接口。
如前所述,lambda表达式不是独立执行的,而是构成一个函数式接口定义的抽象类型的实现,该函数式接口定义了它的目标类型。
例子:
首先声名函数式接口的一个引用:
MyNumvber myNumber;
将lambda表达式赋给该接口
myNumber =()->123.45
当目标类型上下文中出现lambda表达式时,会自动创建实现了函数式接口的一个类的实例。函数式接口声名的类的行为由lambda表达式定义。当通过目标调用该方法时就会执行lambda表达式。因此,lambda表达式是实现代码段转换为对象的方法。
三、示例
1.牛刀小试
// A functional interface.
interface MyNumber {
double getValue();
}
class LambdaDemo {
public static void main(String args[])
{
MyNumber myNum; // declare an interface reference
// Here, the lambda expression is simply a constant expression.
// When it is assigned to myNum, a class instance is
// constructed in which the lambda expression provides an override
// of the getValue() method in MyNumber.
myNum = () -> 123.45;
// Call getValue(), which is overridden by the previously assigned
// lambda expression.
System.out.println("A fixed value: " + myNum.getValue());
// Here, a more complex expression is used.
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());
// A lambda expression must be compatible with the method
// defined by the functional interface. Therefore, this won't work:
// myNum = () -> "123.03"; // Error!
}
}
OUTPUT:
A fixed value: 123.45
A random value: 18.048278950868447
Another random value: 7.713414439363719
2.块lambda表达式
class Block{
interface StrFunc{
String func(String n);
}
}
class BlockLambda{
public static void main(String[] args) {
Block.StrFunc strFunc;
strFunc=(what)->{
String result ="";
for(int i=what.length()-1;i>=0;i--){
result+=what.charAt(i);
}
return result;
};
System.out.println("lambda reversed is "+strFunc.func("lambda"));
}
}
当lambda表达式出现return语句,从lambda表达体返回,而不是从包围lambda的方法体返回。
3.泛型函数式接口
lambda表达式自身不能定义参数类型,因此lambda表达式不能是泛型。而与lambda表达式关联的接口可以是泛型。此时,lambda表达式的目标类型由声名函数式接口引用时所指定的参数类型决定。
现在就比较好理解了,我们利用泛型特点(扩展了代码的重用能力Java泛型基础
)来简化接口的数量。
class GenericInterface{
interface GenericFunctional<T>{
T func(T t);
}
}
public class GenericFunctionalInterfaceDemo {
public static void main(String[] args) {
GenericInterface.GenericFunctional<String> genericFunctional=(str)->{
String result="";
for(int i=str.length()-1;i>=0;i--){
result+=str.charAt(i);
}
return result;
};
System.out.println("lambda reversed is "+genericFunctional.func("lambda"));
GenericInterface.GenericFunctional<Integer> genericFunctional1=(fac)->{
Integer s=1;
for(int i=1;i<=fac;i++){
s=i*s;
}
return s;
};
System.out.println("the factoral of 5 is " +genericFunctional1.func(5));
}
}
OUTPUT:
lambda reversed is adbmal
the factoral of 5 is 120