Lambda表达式 Lamabda表达式也称为闭包,是java8推出的新特性,Lamabda表达式允许吧函数作为一个方法的参数(函数作为参数传递进方法中)。作用是可以使代码变得更加简洁紧凑。
特征:
可选类型声明:不一定要声明类型,编译器可以根据上下文进行自动推断。
可选的参数括号:有一个参数不需要圆括号,多个则要。
可选的大括号:主题只有一条语句不需要大括号。
可选的返回关键字:只有一个表达式返回值编译器会自动返回值,大括号则需要自行定义返回值。
Lambda例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 package lambda;public class Java8Test { public static void main (String []args) { Java8Test tester=new Java8Test(); MathOperation addition=(int a,int b)->a+b; MathOperation subtraction=(int a,int b)->a-b; MathOperation multiplication=(int a,int b)->{return a*b; }; MathOperation division =(int a,int b)->a/b; System.out.println("加:" +tester.operate(10 ,5 ,addition)); System.out.println("减:" +tester.operate(10 ,5 ,subtraction)); System.out.println("乘:" +tester.operate(10 ,5 ,multiplication)); System.out.println("除:" +tester.operate(10 ,5 ,division)); GreetingService greetService1=message->System.out.println("Hello" +" " +message); GreetingService greetService2=(String message)->System.out.println("Hello" +" " +message); greetService1.greetService("NIHAO" ); greetService2.greetService("BUNZHU" ); MathOperation add=(int a,int b)->a+b; System.out.println(add.operation(1 ,2 )); } interface MathOperation { int operation (int a,int b) ; } interface GreetingService { void greetService (String message) ; } private int operate (int a,int b,MathOperation mathOperation) { return mathOperation.operation(a,b); } }
使用Lambda表达式需要注意以下几点:
Lambda表达式主要用来执行内执行的方法类型的接口。例如,一个简单方法接口,我们使用了各种类型的Lambda表达式来定义MathOperation接口的方法。然后定义了sayMessage的执行。
Lambda表达式免去了使用匿名方法的麻烦,并且给予java简单但是强大的函数化编程能力。
使用Lambda表达式解决comparable的方法:
Employee(不需要implement comparator了)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 package songyan.chp6.homework.question7;public class Employee { private String id; private String name; private double salary; public Employee () { } public Employee (String id,String name,double salary) { this .id=id; this .name=name; this .salary=salary; } public void setId (String id) { this .id=id; } public void setName (String name) { this .name=name; } public void setSalary (double salary) { this .salary=salary; } public String getId () { return id; } public String getName () { return name; } public double getSalary () { return salary; } public String toString () { return id+"," +name+"," +salary; } }
重点:Test类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 package songyan.chp6.homework.question7;import java.util.Arrays;public class Test { public static void main (String []args) { Employee[] es = new Employee[5 ]; es[0 ] = new Employee("001" , "zhang" , 5000 ); es[1 ] = new Employee("002" , "li" , 8000 ); es[2 ] = new Employee("003" , "zhao" , 6000 ); es[3 ] = new Employee("004" , "song" , 6500 ); es[4 ] = new Employee("005" , "zhu" , 9500 ); Arrays.sort(es,(o1,o2)->{if (o1.getSalary()>o2.getSalary())return 1 ; else return -1 ;}); for (Employee e: es) { System.out.println(e); } Arrays.sort(es,(o1,o2)->{if (o1.getName().length()>o2.getName().length())return 1 ; else return -1 ;}); for (Employee e: es) { System.out.println(e); } } }
可以对比lambda表达式和普通接口实现方法的对比。
变量作用域 lambda表达式只能引用标记了final的外层局部变量,这就是说不能在lamabda的内部修改定义在域外的局部变量,否则会编译错误。此外不允许在lambda表达式中声明与局部变量同名的参数或者局部变量。
1 2 3 4 5 6 int num = 1 ; Converter<Integer, String> s = (param) -> System.out.println(String.valueOf(param + num)); s.convert(2 ); num = 5 ; final
1 2 String first = "" ; Comparator<String> comparator = (first, second) -> Integer.compare(first.length(), second.length());
声明同名变量。