一、Lambda表达式
基本语法:
lambdaParameters->lambdaBody
lambdaParameters传递参数,lambdaBody用于编写逻辑,lambda表达式会生成一个函数式接口实现实例,因此可以将一个lambda表达式赋值给函数式接口引用。lambdaBody中的逻辑内容不会在定义时执行,在实际函数式接口调用时才会执行。
() - > {}//入参为空,返回为空
() -> 42//常量函数
(x) -> x+1
(int x) -> x+1
lambda表达式根据参数声明包含两个大类参数类型未声明,参数类型声明,不同于匿名内部类,lambda表达式的body共享上下文类的this变量,另一个注意点是lambda表达式的body部分可以使用外部变量,变量需要是final或者effectively final,
effectively final的定义如下:
如果是有初始值的变量,需满足:
1、没有声明为final
2、从未出现在赋值语句的左值部分
3、从未作为一个变量被++或者--之类的递增递减操作符操作过
如果是没有初始值的变量则需要满足
1、没有声明为final
2、在实际赋值前,绝对未赋值或者未绝对赋值
3、从未作为一个变量被C++或--之类的递增递减操作符操作过
通常方法,构造函数、lambda和异常的参数会被认为是effectively final
public class FunctionTest { public void getFunctionName(){ int n = 10; Consumer<Integer> func = (x) -> { x = x+n; n = 2;//编译前需要把本行代码注释掉,依据有初始变量需满足的条件2 System.out.println(x); }; func.accept(13); } public static void main(String[] args){ FunctionTest test = new FunctionTest(); test.getFunctionName(); } }
二、方法引用表达式
方法引用表达式是定义另一类函数式接口实现的方式,在JAVA8引入了函数式接口之后,可以把一个lambda表达式作为一个函数式接口实现实例赋值给一个函数式接口,另一种方式是直接使用方法引用,方法引用是使用方式:对象名::方法名,类、对象、数组、泛型引用方式均不同,下面是使用示例:
public class FunctionTest { public static Integer staticMethod(int x){ System.out.println(x+10); return x+10; } public static void main(String[] args){ //类的静态方法 Function<Integer,Integer> staticFunc = FunctionTest::staticMethod; staticFunc.apply(20); //对象方法 Function<String,String> instanceFunc = String::trim; System.out.println(instanceFunc.apply(" abd c")); Consumer<int[]> c1 = Arrays::sort; int[] array = new int[]{1,3,45,4}; c1.accept(array); Arrays.stream(array).forEach(x->System.out.print(x+",")); System.out.println(); Function<Integer,int[]> c2 = int[]::new; int[] c2Array = c2.apply(10); System.out.println(c2Array.length); } }
总结:
lambda表达式和方法引用表达式都可以赋值给函数式接口,证明他们也都指向一个函数或者方法,两者的使用场景显而易见,lambda表达式方便在行内快速声明一个方法并且指向一个函数,而方法引用表达式则是基于已有的方法。
浙公网安备 33010602011771号