目录
♫什么是Lambda表达式
♫Lambda表达式的语法
♫函数式接口
♫Lambda表达式的使用
♫变量捕获
♫ Lambda表达式在集合中的使用
♪Collection的foreach():
♪List的sort():
♪Map的foreach()
♫什么是Lambda表达式
Lambda 表达式是 Java SE 8中一个重要的新特性,它是一种匿名函数,常作为函数式编程的一部分,用于向函数传递行为作为参数,或者用于将行为作为返回值返回。 Lambda表达式提供了一个正常的参数列表和一个使用这些参数的主体(body, 可以是一个表达式或一个代码块)。
♫Lambda表达式的语法
基本语法 : (parameters) ->{ 方法体 }①. paramaters :类似方法中的形参列表,这里的参数是函数式接口里的参数。(参数类型可以明确的声明 ,也可不声明而由 JVM 隐含的推断;当只有一个推断类型时可以省略掉圆括号)②. -> :可理解为 “ 被用于 ” 的意思③. 方法体 :可以是表达式也可以代码块,是函数式接口里方法的实现。(代码块可返回一个值或者什么都不返回,这里的代码块块等同于方法的方法体;如果是表达式,也可以返回一个值或者什么都不反回)//1. 不需要参数,返回值为2 ()->2; //2. 接收一个参数(数字类型),返回其2倍的值 x->2*x; //3. 接受2个参数(数字),并返回他们的和 (x,y)->x+y; //4. 接收2个int型整数,返回他们的乘积 (int x,int y)->x*y; //5. 接受一个string对象,并在控制台打印,不返回任何值 (String s)->System.out.print(s);
注:①.->前只有一个参数,()可以省略;②.->后只有一条语句,{}可以省略;③.->后只有return语句,return可以去掉;④.()里 的参数类型可以省略,如果要省略,每个参数的类型都要省略。
♫函数式接口
要了解 Lambda 表达式 , 还需要先了解什么是函数式接口。函数式接口是一种特殊的接口,它的接口里有且只有一个抽象方法:@FunctionalInterface interface A { //抽象方法有且只有一个 public void fun(); //可以有被default修饰的具体方法 default void fun2() { System.out.println("JDK1.8新特性,default默认方法可以有具体的实现"); } }
注:
①.如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口。
②.可以在接口上方加上@FunctionalInterface注释,让编译器帮助我们检查该接口是不是一个函数式接口。
③.JDK1.8之后,函数式接口里允许存在default方法修饰的具体方法。
♫Lambda表达式的使用
我们先定义几个函数式接口:
//无返回值无参数 @FunctionalInterface interface NoParameterNoReturn { void test(); } //无返回值一个参数 @FunctionalInterface interface OneParameterNoReturn { void test(int a); } //无返回值多个参数 @FunctionalInterface interface MoreParameterNoReturn { void test(int a,int b); } //有返回值无参数 @FunctionalInterface interface NoParameterReturn { int test(); } //有返回值一个参数 @FunctionalInterface interface OneParameterReturn { int test(int a); } //有返回值多参数 @FunctionalInterface interface MoreParameterReturn { int test(int a,int b); }
下面我们通过Lambda表达式对上面几个函数式接口进行实例化操作:
public class Test { public static void main(String[]args) { //无参数无返回值 NoParameterNoReturn noParameterNoReturn = () -> { System.out.println("无参数无返回值"); }; noParameterNoReturn.test(); //一个参数无返回值 OneParameterNoReturn oneParameterNoReturn = (int a) -> { System.out.println("一个参数无返回值:" + a); }; oneParameterNoReturn.test(10); //多个参数无返回值 MoreParameterNoReturn moreParameterNoReturn = (int a, int b) -> { System.out.println("多个参数无返回值:" + a + "" + b); }; moreParameterNoReturn.test(20, 30); //有返回值无参数 NoParameterReturn noParameterReturn = () -> { System.out.println("有返回值无参数"); return 40; }; int ret = noParameterReturn.test(); System.out.println(ret); //有返回值有一个参数 OneParameterReturn oneParameterReturn = (int a) -> { System.out.println("有返回值有一个参数"); return a; }; ret = oneParameterReturn.test(50); System.out.println(ret); //有返回值多个参数 MoreParameterReturn moreParameterReturn = (int a, int b) -> { System.out.println("有返回值多个参数"); return a + b; }; ret = moreParameterReturn.test(60, 70); System.out.println(ret); } }
注:Lambda表达式只能应用于函数式接口。
♫变量捕获
变量捕获是指将外部类中的变量复制到内部类中,这样内部类就可以在外部类的作用域之外访问这些变量。
匿名内部类和lambda表达式都存在变量捕获:
@FunctionalInterface interface B { void fun(); } public class Test { public static void main(String[] args) { int a = 10; //匿名内部类: B b1 = new B() { @Override public void fun() { System.out.println("匿名内部类a=" + a); } }; b1.fun(); //Lambda表达式: B b2 = () -> { System.out.println("Lambda表达式a=" + a); }; b2.fun(); } }
运行结果如下:
需要注意的是:被捕获的变量要么是被final修饰,要么是隐式 final 的(在使用之前没有被修改):
@FunctionalInterface interface B { void fun(); } public class Test { public static void main(String[] args) { int a = 10; //a = 11;//① //匿名内部类: B b1 = new B() { @Override public void fun() { //a = 11;//② System.out.println("匿名内部类a=" + a); } }; b1.fun(); //a = 11;//③ } }
在①、②、③任意一处去掉注释都会报错:
♫ Lambda表达式在集合中的使用
为了能够让 Lambda 和 Java 的集合类集更好的一起使用,Java集合中新增了部分接口,以便与 Lambda 表达式对接:
接口 新增方法 Collection removeIf()、spliterator()、stream()、parallelStream()、forEach() List replaceAll()、sort()Map getOrDefault()、forEach()、replaceAll()、putIfAbsent()、remove()、replace()、computeIfAbsent()、computeIfPresent()、compute()、merge()♪Collection的foreach():
foreach()的部分源码:
foreach()的应用:
public class Test { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(3); list.add(2); list.forEach(s-> System.out.print(s+" ")); } }
运行结果:
♪List的sort():
sort()的部分源码:
sort()的应用:
class Test2 { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<>(); list.add(1); list.add(3); list.add(2); list.sort((str1,str2)->str1-str2); System.out.println(list); } }
运行结果:
♪Map的foreach()
foreach()的部分源码:
foreach()的应用:
class Test3 { public static void main(String[] args) { HashMap<String, Integer> map = new HashMap<>(); map.put("a", 1); map.put("b", 2); map.put("c",3); map.forEach((k,v)->System.out.println(k+"="+v)); } }
运行结果: