Lambda表达式 一、Lambda表达式简介 什么是Lambda? Lambda是JAVA 8添加的新特性,说白了,Lambda是一个匿名函数
为什么使用Lambda 使用Lambda表达式可以对一个接口的方法进行非常简洁的实现
Lambda对接口的要求 虽然可以使用Lambda表达式对某些接口进行简单的实现,但是并不是所有的接口都可以用Lambda表达式来实现,要求接口中定义的必须要实现的抽象方法只能是一个
1 2 在JAVA8中 ,对接口加了一个新特性:default 可以使用default对接口方法进行修饰,被修饰的方法在接口中可以默认实现
@FunctionalInterface 修饰函数式接口的,接口中的抽象方法只有一个
二、Lambda的基础语法 1.语法
2.创建多个接口 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 59 60 61 62 63 64 65 66 67 68 69 70 71 @FunctionalInterface public interface LambdaNoneReturnNoneParmeter { void test () ; } @FunctionalInterface public interface LambdaNoneReturnSingleParmeter { void test (int n) ; } @FunctionalInterface public interface LambdaNoneReturnMutipleParmeter { void test (int a,int b) ; } @FunctionalInterface public interface LambdaSingleReturnNoneParmeter { int test () ; } @FunctionalInterface public interface LambdaSingleReturnSingleParmeter { int test (int n) ; } @FunctionalInterface public interface LambdaSingleReturnMutipleParmeter { int test (int a,int b) ; }
3.创建测试类 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 59 60 61 62 63 64 65 66 67 68 69 70 71 72 package com.alan.learn.syntax;import com.alan.learn.interfaces.*;public class Syntax1 { public static void main (String[] args) { LambdaNoneReturnNoneParmeter lambda1=()->{ System.out.println("hello word" ); }; lambda1.test(); LambdaNoneReturnSingleParmeter lambda2=(int n)->{ System.out.println("参数是:" +n); }; lambda2.test(10 ); LambdaNoneReturnMutipleParmeter lambda3=(int a,int b)->{ System.out.println("参数和是:" +(a+b)); }; lambda3.test(10 ,12 ); LambdaSingleReturnNoneParmeter lambda4=()->{ System.out.println("lambda4:" ); return 100 ; }; int ret=lambda4.test(); System.out.println("返回值是:" +ret); LambdaSingleReturnSingleParmeter lambda5=(int a)->{ return a*2 ; }; int ret2= lambda5.test(3 ); System.out.println("单个参数,lambda5返回值是:" +ret2); LambdaSingleReturnMutipleParmeter lambda6=(int a,int b)->{ return a+b; }; int ret3=lambda6.test(12 ,14 ); System.out.println("多个参数,lambda6返回值是:" +ret3); } } 输出结果: hello word 参数是:10 参数和是:22 lambda4: 返回值是:100 单个参数,lambda5返回值是:6 多个参数,lambda6返回值是:26
三、语法精简 针对上述基础语法的精简
1.参数类型精简 1 2 3 4 5 6 7 8 9 10 11 12 13 LambdaNoneReturnMutipleParmeter lambda1=(int a,int b)-> { System.out.println("hello world" ); }; 可以精简为: LambdaNoneReturnMutipleParmeter lambda1=(a,b)-> { System.out.println("hello world" ); };
2.参数小括号精简 1 2 3 4 5 6 7 8 9 10 11 LambdaNoneReturnSingleParmeter lambda2=(a)->{ System.out.println("hello world" ); }; 可以精简为: LambdaNoneReturnSingleParmeter lambda2= a->{ System.out.println("hello world" ); };
3.方法大括号精简 1 2 3 4 5 6 7 8 9 LambdaNoneReturnSingleParmeter lambda3=a->{ System.out.println("hello world" ); }; 可以精简为: LambdaNoneReturnSingleParmeter lambda3=a->System.out.println("hello world" );
4.大括号精简补充 1 2 3 4 5 6 7 8 9 LambdaSingleReturnNoneParmeter lambda4=()->{ return 10 ; }; 可以精简为: LambdaSingleReturnNoneParmeter lambda4=()->10 ;
5.多参数,有返回值 精简 1 2 3 4 5 LambdaSingleReturnNoneParmeter lambda4=(a,b)->{ return a+b; }; 可以精简为: LambdaSingleReturnMutipleParmeter lambda5=(a,b)->a+b;
四、Lambda语法进阶 1.方法引用(普通方法与静态方法) 在实际应用过程中,一个接口在很多地方都会调用同一个实现,例如:
1 2 LambdaSingleReturnMutipleParmeter lambda1=(a,b)->a+b; LambdaSingleReturnMutipleParmeter lambda2=(a,b)->a+b;
这样一来每次都要写上具体的实现方法 a+b,如果需求变更,则每一处实现都需要更改,基于这种情况,可以将后续的是实现更改为已定义的 方法,需要时直接调用就行
语法:
例:
```java package com.alan.learn.syntax;import com.alan.learn.interfaces.LambdaSingleReturnSingleParmeter;/**
@author Alan
@version 1.0
@date 2020-05-27 11:48
/ public class Syntax3 {
public static void main(String[] args) {
LambdaSingleReturnSingleParmeter lambda1=a->a*2;
LambdaSingleReturnSingleParmeter lambda2=a->a*2;
LambdaSingleReturnSingleParmeter lambda3=a->a*2;
//简化
LambdaSingleReturnSingleParmeter lambda4=a->change(a);
//方法引用
LambdaSingleReturnSingleParmeter lambda5=Syntax3::change;
}
/**
自定义的实现方法
/ private static int change(int a){ return a*2; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ### 2.方法引用(构造方法) ### 目前有一个实体类 ```java public class Person { public String name; public int age; public Person() { System.out.println("Person的无参构造方法执行"); } public Person(String name, int age) { this.name = name; this.age = age; System.out.println("Person的有参构造方法执行"); } }
需求
两个接口,各有一个方法,一个接口的方法需要引用Person的无参构造,一个接口的方法需要引用Person的有参构造 用于返回两个Person对象,例:
1 2 3 4 5 6 7 8 9 interface PersonCreater { Person getPerson () ; } interface PersonCreater2 { Person getPerson (String name,int age) ; }
那么可以写作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Syntax4 { public static void main (String[] args) { PersonCreater creater=()->new Person(); PersonCreater creater1=Person::new ; Person a=creater1.getPerson(); PersonCreater2 creater2=Person::new ; Person b=creater2.getPerson("张三" ,18 ); } }
注意:是引用无参构造还是引用有参构造 在于接口定义的方法参数
五、综合练习 1.集合排序案例 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 package com.alan.exercise;import com.alan.learn.data.Person;import java.util.ArrayList;public class Exercise1 { public static void main (String[] args) { ArrayList<Person> list=new ArrayList<>(); list.add(new Person("张三" ,10 )); list.add(new Person("李四" ,12 )); list.add(new Person("王五" ,13 )); list.add(new Person("赵六" ,14 )); list.add(new Person("李雷" ,11 )); list.add(new Person("韩梅梅" ,8 )); list.add(new Person("jack" ,10 )); System.out.println("排序前:" +list); list.sort((o1, o2) -> o2.age-o1.age); System.out.println("排序后:" +list); } }
2.Treeset排序案例 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 package com.alan.exercise;import com.alan.learn.data.Person;import java.util.TreeSet;public class Exercise2 { public static void main (String[] args) { TreeSet<Person> set=new TreeSet<>((o1, o2) ->{ if (o1.age>=o2.age){ return -1 ; }else { return 1 ; } }); set.add(new Person("张三" ,10 )); set.add(new Person("李四" ,12 )); set.add(new Person("王五" ,13 )); set.add(new Person("赵六" ,14 )); set.add(new Person("李雷" ,11 )); set.add(new Person("韩梅梅" ,8 )); set.add(new Person("jack" ,10 )); System.out.println(set); } }
3.集合的遍历 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 package com.alan.exercise;import java.util.ArrayList;import java.util.Collections;public class Exercise3 { public static void main (String[] args) { ArrayList<Integer> list=new ArrayList<>(); Collections.addAll(list,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,9 ); list.forEach(ele->{ if (ele%2 ==0 ){ System.out.println(ele); } }); } }
4.删除集合中满足条件的元素 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 package com.alan.exercise;import com.alan.learn.data.Person;import java.util.ArrayList;public class Exercise4 { public static void main (String[] args) { ArrayList<Person> list=new ArrayList<>(); list.add(new Person("张三" ,10 )); list.add(new Person("李四" ,12 )); list.add(new Person("王五" ,13 )); list.add(new Person("赵六" ,14 )); list.add(new Person("李雷" ,11 )); list.add(new Person("韩梅梅" ,8 )); list.add(new Person("jack" ,10 )); list.removeIf(ele->ele.age>10 ); System.out.println(list); } }
5.开辟一条线程 做一个数字的输出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 package com.alan.exercise;public class Exercise5 { public static void main (String[] args) { Thread t=new Thread(()->{ for (int i=0 ;i<100 ;i++){ System.out.println(i); } }); t.start(); } }
六、系统内置的函数式接口 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 package com.alan.functional;import java.util.function.*;public class FunctionalInterface { public static void main (String[] args) { } }
七、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 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 package com.alan.closure;import java.util.function.Supplier;public class ClosureDemo { public static void main (String[] args) { int n=getNumber().get(); System.out.println(n); } private static Supplier<Integer> getNumber () { int num=10 ; return ()->{ return num; }; } } ************************************************************************* package com.alan.closure;import java.util.function.Consumer;public class ClosureDemo2 { public static void main (String[] args) { int a=10 ; Consumer<Integer> c=ele->{ System.out.println(a+1 ); }; c.accept(1 ); } }