IT序号网

Java1.8之Lambda表达式知识解答

luoye 2021年06月03日 编程语言 136 0

1、Java8的lambda表达式,通过lambda表达式可以替代我们之前写的匿名内部类来实现接口。lambda表达式本质是一个匿名函数。

 1 package com.demo.main; 
 2  
 3 public class LambdaMain { 
 4  
 5     public static void main(String[] args) { 
 6  
 7         // 1、创建一个匿名内部类 
 8         Addition addition = new Addition() { 
 9  
10             @Override 
11             public int add(int a, int b) { 
12  
13                 return a + b; 
14             } 
15  
16         }; 
17         // 传统的匿名内部类来实现接口。 
18         System.out.println("调用匿名内部类来实现接口:" + addition.add(2, 3)); 
19  
20         // 2、Java8的lambda表达式,通过lambda表达式可以替代我们之前写的匿名内部类来实现接口。 
21         // lambda表达式本质是一个匿名函数。 
22         // 2.1、lambda由三部分组成,()是参数列表,->剪头符号,{}代表方法体。 
23         Addition a2 = (int a, int b) -> { 
24             return a + b; 
25         }; 
26         System.out.println("lambda表达式a2:" + a2.add(3, 3)); 
27  
28         // 2.2、可以省略参数列表里面的参数类型 
29         Addition a3 = (a, b) -> { 
30             return a + b; 
31         }; 
32         System.out.println("lambda表达式a3:" + a3.add(3, 3)); 
33  
34     } 
35  
36     /** 
37      *  
38      * @author 创建一个接口,定义一个方法 
39      * 
40      */ 
41     interface Addition { 
42  
43         /** 
44          * 加法的方法 
45          *  
46          * @param a 
47          * @param b 
48          * @return 
49          */ 
50         int add(int a, int b); 
51     } 
52  
53 }

2、Lambda表达式语法,形如(int a, int b) -> {return a + b;},lambda本质就是一个(匿名)函数,匿名函数,就是没有方法名称的函数。

1 一般函数结构类似,如下所示: 
2 int add(int a, int b){ 
3     return  a + b; 
4 } 
5  
6 一般函数的,结构如:返回值 方法名称(参数列表) 方法体。

3、而Lamdba表达式函数,只有参数列表和方法体。结构如:(参数列表) -> {方法体};

详细说明,如下所示:

  1)、()括号用来描述参数列表。
  2)、{}大括号用来描述方法体。
  3)、->尖括号,Lambda运算符,可以叫做箭头符号,或者goes to。

4、Lambda表达式语法,关于接口方法参数、无参、单个参数、两个参数、有返回值、没有返回值的情况。如何来根据lambda来返回接口函数。

  1 package com.demo.main; 
  2  
  3 public class LambdaMain { 
  4  
  5     public static void main(String[] args) { 
  6         // 1、无参数无返回值 
  7         MethodNoReturnNoParam methodNoReturnNoParam = () -> { 
  8             System.out.println("无参数无返回值"); 
  9         }; 
 10         methodNoReturnNoParam.lambda1(); 
 11  
 12         // 2、单个参数无返回值 
 13         MethodNoReturnOneParam methodNoReturnOneParam = (int a) -> { 
 14             System.out.println("单个参数无返回值,a = " + a); 
 15         }; 
 16         methodNoReturnOneParam.lambda2(3); 
 17  
 18         // 3、两个参数无返回值 
 19         MethodNoReturnTwoParam methodNoReturnTwoParam = (int a, int b) -> { 
 20             System.out.println("两个参数无返回值,a + b = " + (a + b)); 
 21         }; 
 22         methodNoReturnTwoParam.lambda3(3, 4); 
 23  
 24         // 4、无参数有返回值 
 25         MethodReturnNoParam methodReturnNoParam = () -> { 
 26             return 8; 
 27         }; 
 28         System.out.println("无参数有返回值:" + methodReturnNoParam.lambda4()); 
 29  
 30         // 5、一个参数有返回值 
 31         MethodReturnOneParam methodReturnOneParam = (int a) -> { 
 32             return a; 
 33         }; 
 34         System.out.println("一个参数有返回值,a = " + methodReturnOneParam.lambda5(9)); 
 35  
 36         // 6、一个参数有返回值 
 37         MethodReturnTwoParam methodReturnTwoParam = (int a, int b) -> { 
 38             return a + b; 
 39         }; 
 40         System.out.println("一个参数有返回值,a + b = " + methodReturnTwoParam.lambda6(9, 9)); 
 41  
 42     } 
 43  
 44     /** 
 45      * 1、无参数无返回值 
 46      *  
 47      * @author 
 48      * 
 49      */ 
 50     interface MethodNoReturnNoParam { 
 51  
 52         void lambda1(); 
 53     } 
 54  
 55     /** 
 56      * 2、单个参数无返回值 
 57      *  
 58      * @author 
 59      * 
 60      */ 
 61     interface MethodNoReturnOneParam { 
 62  
 63         void lambda2(int a); 
 64     } 
 65  
 66     /** 
 67      * 3、两个参数无返回值 
 68      *  
 69      * @author 
 70      * 
 71      */ 
 72     interface MethodNoReturnTwoParam { 
 73  
 74         void lambda3(int a, int b); 
 75     } 
 76  
 77     /** 
 78      * 4、无参数有返回值 
 79      *  
 80      * @author 
 81      * 
 82      */ 
 83     interface MethodReturnNoParam { 
 84  
 85         int lambda4(); 
 86     } 
 87  
 88     /** 
 89      * 5、一个参数有返回值 
 90      *  
 91      * @author 
 92      * 
 93      */ 
 94     interface MethodReturnOneParam { 
 95  
 96         int lambda5(int a); 
 97     } 
 98  
 99     /** 
100      * 6、两个参数有返回值 
101      *  
102      * @author 
103      * 
104      */ 
105     interface MethodReturnTwoParam { 
106  
107         int lambda6(int a, int b); 
108     } 
109  
110 }

5、Lambda表达式语法,精简写法,如下所示:

  1)、参数类型可以省略。
  2)、假如只有一个参数,()括号可以省略。
  3)、如果方法体只有一条语句,{}大括号可以省略。
  4)、如果方法体中唯一的语句是return返回语句,那省略大括号的同时return关键词也要省略掉。

 1 package com.demo.main; 
 2  
 3 public class LambdaMain { 
 4  
 5     public static void main(String[] args) { 
 6         // 1、无参数无返回值 
 7         MethodNoReturnNoParam methodNoReturnNoParam = () -> System.out.println("无参数无返回值"); 
 8         methodNoReturnNoParam.lambda1(); 
 9  
10         // 2、单个参数无返回值 
11         MethodNoReturnOneParam methodNoReturnOneParam = a -> System.out.println("单个参数无返回值,a = " + a); 
12         methodNoReturnOneParam.lambda2(3); 
13  
14         // 3、两个参数无返回值 
15         MethodNoReturnTwoParam methodNoReturnTwoParam = (a, b) -> System.out.println("两个参数无返回值,a + b = " + (a + b)); 
16         methodNoReturnTwoParam.lambda3(3, 4); 
17  
18         // 4、无参数有返回值 
19         MethodReturnNoParam methodReturnNoParam = () -> 8; 
20         System.out.println("无参数有返回值:" + methodReturnNoParam.lambda4()); 
21  
22         // 5、一个参数有返回值 
23         MethodReturnOneParam methodReturnOneParam = a -> a + 10; 
24         System.out.println("一个参数有返回值,a = " + methodReturnOneParam.lambda5(9)); 
25  
26         // 6、一个参数有返回值 
27         MethodReturnTwoParam methodReturnTwoParam = (a, b) -> a + b; 
28         System.out.println("一个参数有返回值,a + b = " + methodReturnTwoParam.lambda6(9, 9)); 
29  
30     } 
31  
32     /** 
33      * 1、无参数无返回值 
34      *  
35      * @author 
36      * 
37      */ 
38     interface MethodNoReturnNoParam { 
39  
40         void lambda1(); 
41     } 
42  
43     /** 
44      * 2、单个参数无返回值 
45      *  
46      * @author 
47      * 
48      */ 
49     interface MethodNoReturnOneParam { 
50  
51         void lambda2(int a); 
52     } 
53  
54     /** 
55      * 3、两个参数无返回值 
56      *  
57      * @author 
58      * 
59      */ 
60     interface MethodNoReturnTwoParam { 
61  
62         void lambda3(int a, int b); 
63     } 
64  
65     /** 
66      * 4、无参数有返回值 
67      *  
68      * @author 
69      * 
70      */ 
71     interface MethodReturnNoParam { 
72  
73         int lambda4(); 
74     } 
75  
76     /** 
77      * 5、一个参数有返回值 
78      *  
79      * @author 
80      * 
81      */ 
82     interface MethodReturnOneParam { 
83  
84         int lambda5(int a); 
85     } 
86  
87     /** 
88      * 6、两个参数有返回值 
89      *  
90      * @author 
91      * 
92      */ 
93     interface MethodReturnTwoParam { 
94  
95         int lambda6(int a, int b); 
96     } 
97  
98 }

6、方法引用,如果多个lamdba表达式实现函数都是一样的话,可以封装成通用方法,以方便维护,此时可以使用方法引用实现。

  语法规则:对象::方法。假如是static静态方法,可以直接类名::方法。

 1 package com.demo.main; 
 2  
 3 public class LambdaMain { 
 4  
 5     public static void main(String[] args) { 
 6 //        // 创建对象 
 7 //        LambdaMain lambdaMain = new LambdaMain(); 
 8 //        // 采用对象引用的方式进行实现 
 9 //        MethodReturnOneParam methodReturnOneParam_1 = lambdaMain::add; 
10 //        System.out.println(methodReturnOneParam_1.lambda5(10)); 
11 // 
12 //        // 采用对象引用的方式进行实现 
13 //        MethodReturnOneParam methodReturnOneParam_2 = lambdaMain::add; 
14 //        System.out.println(methodReturnOneParam_2.lambda5(40)); 
15          
16          
17         // 创建对象 
18         // 采用静态对象引用的方式进行实现 
19         MethodReturnOneParam methodReturnOneParam_1 = LambdaMain::addStatic; 
20         System.out.println(methodReturnOneParam_1.lambda5(10)); 
21  
22         // 采用静态对象引用的方式进行实现 
23         MethodReturnOneParam methodReturnOneParam_2 = LambdaMain::addStatic; 
24         System.out.println(methodReturnOneParam_2.lambda5(40)); 
25     } 
26  
27     /** 
28      * 方法引用,如果多个lamdba表达式实现函数都是一样的话,可以封装成通用方法,以方便维护,此时可以使用方法引用实现。 
29      *  
30      * @param a 
31      * @return 
32      */ 
33     public int add(int a) { 
34         return a + 10; 
35     } 
36  
37     /** 
38      * 静态方法引用 
39      *  
40      * @param a 
41      * @return 
42      */ 
43     public static int addStatic(int a) { 
44         return a + 10; 
45     } 
46  
47     /** 
48      * 5、一个参数有返回值 
49      * 
50      * @author 
51      * 
52      */ 
53     interface MethodReturnOneParam { 
54  
55         int lambda5(int a); 
56     } 
57  
58 }

7、构造方法引用,如果函数式接口的实现切好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用。

语法规则:类名::new。

 1 package com.demo.po; 
 2  
 3 public class Dog { 
 4  
 5     private String name; 
 6     private int age; 
 7  
 8     public String getName() { 
 9         return name; 
10     } 
11  
12     public void setName(String name) { 
13         this.name = name; 
14     } 
15  
16     public int getAge() { 
17         return age; 
18     } 
19  
20     public void setAge(int age) { 
21         this.age = age; 
22     } 
23  
24     @Override 
25     public String toString() { 
26         return "Dog [name=" + name + ", age=" + age + "]"; 
27     } 
28  
29     public Dog(String name, int age) { 
30         System.out.println("含参构造函数!"); 
31         this.name = name; 
32         this.age = age; 
33     } 
34  
35     public Dog() { 
36         System.out.println("无参构造函数!"); 
37     } 
38  
39 }
 1 package com.demo.main; 
 2  
 3 import com.demo.po.Dog; 
 4  
 5 public class LambdaMain { 
 6  
 7     public static void main(String[] args) { 
 8         // 1、使用lambda表达式的方式使用 
 9         DogService dogService1_0 = () -> { 
10             return new Dog(); 
11         }; 
12         dogService1_0.getDog(); 
13  
14         // 2、简化方式 
15         DogService dogService1_1 = () -> new Dog(); 
16         dogService1_1.getDog(); 
17  
18         // 3、构造方法引用,如果函数式接口的实现切好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用。 
19         DogService dogService1_2 = Dog::new; 
20         dogService1_2.getDog(); 
21  
22         // 4、构造方法引用,有参构造函数调用 
23         DogService2 dogService2_1 = Dog::new; 
24         dogService2_1.getDog("小黄", 2); 
25  
26     } 
27  
28     interface DogService { 
29  
30         /** 
31          * 获取到一只无名狗 
32          *  
33          * @return 
34          */ 
35         Dog getDog(); 
36     } 
37  
38     interface DogService2 { 
39  
40         /** 
41          * 获取到一个有名称的狗 
42          *  
43          * @param name 
44          * @param age 
45          * @return 
46          */ 
47         Dog getDog(String name, int age); 
48     } 
49  
50 }

8、集合使用lambda表达式对数据进行排序,遍历等操作。对于参数是接口函数的方法,需要传递lamdba表达式作为参数进行调用。

 1 package com.demo.main; 
 2  
 3 import java.util.ArrayList; 
 4 import java.util.List; 
 5  
 6 import com.demo.po.Dog; 
 7  
 8 public class LambdaMain { 
 9  
10     public static void main(String[] args) { 
11         List<Dog> list = new ArrayList<Dog>(); 
12         list.add(new Dog("小黄", 5)); 
13         list.add(new Dog("小花", 4)); 
14         list.add(new Dog("旺财", 3)); 
15         list.add(new Dog("团团", 2)); 
16         list.add(new Dog("圆圆", 1)); 
17  
18         // 排序 
19         System.out.println("lambda集合排序!!!"); 
20         // sort的参数是接口函数,需要使用lambda表达式匿名函数形式 
21         list.sort((dog1, dog2) -> dog1.getAge() - dog2.getAge()); 
22         System.out.println(list); 
23         System.out.println(); 
24  
25         // 遍历集合 
26         System.out.println("lamdba集合遍历:"); 
27         list.forEach(System.out::println); 
28     } 
29  
30 }

9、@FunctionalInterface注解,此注解是函数式接口注解,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。这种类型的接口也称为SAM接口,即Single Abstract Method interfaces。

特点:

  1)、接口有且仅有一个抽象方法。
  2)、运行定义静态方法。
  3)、允许定义默认方法。
  4)、允许java.lang.Object中的public方法。
  5)、该注解不是必须的,如果一个接口符合"函数式接口"定义,那么加不加该注解都没有影响。加上该注解能够更好的让编译器进行检查。如果编写的不是函数时接口,但是加上该注解,那么编译器会报错。

 1 package com.demo.main; 
 2  
 3 public class LambdaMain { 
 4  
 5     public static void main(String[] args) { 
 6         FunctionInterface functionInterface = (int a) -> { 
 7             System.out.println("a = " + a); 
 8         }; 
 9         functionInterface.add(10); 
10     } 
11  
12     /** 
13      * 正确的函数式接口 
14      *  
15      * @author biexiansheng 
16      * 
17      */ 
18     @FunctionalInterface 
19     interface FunctionInterface { 
20  
21         /** 
22          * 抽象方法 
23          */ 
24         public void add(int a); 
25  
26         /** 
27          * java.lang.Object中的public方法 
28          *  
29          * @param var 
30          * @return 
31          */ 
32         public boolean equals(Object var); 
33  
34         // 默认的方法 
35         public default void defaultMethod() { 
36             System.out.println("默认的方法!!!"); 
37         } 
38  
39         // 静态方法 
40         public static void staticMethod() { 
41             System.out.println("静态的方法!!!"); 
42         } 
43  
44     } 
45  
46 }

10、系统内置函数式接口,Java8的推出,是以lamdba重要特性,一起推出的,其中系统内置了一系列函数式接口。在jdk的java.util.function包下,有一系列的内置函数式接口:

 1 package com.demo.main; 
 2  
 3 import java.util.function.IntConsumer; 
 4 import java.util.function.IntFunction; 
 5 import java.util.function.IntPredicate; 
 6  
 7 public class LambdaMain { 
 8  
 9     public static void main(String[] args) { 
10         // 在jdk的java.util.function包下,有一系列的内置函数式接口 
11         // 1、使用int函数接口 
12         IntFunction<Integer> intFunction = (a) -> { 
13             return a + 10; 
14         }; 
15         System.out.println(intFunction.apply(20)); 
16          
17         // 2、使用int判断函数接口 
18         final int aa = 20; 
19         IntPredicate intPredicate = (a) -> { 
20             return a == aa; 
21         }; 
22         System.out.println(intPredicate.test(aa)); 
23          
24         // 3、使用int传递参数的形式 
25         IntConsumer intConsumer = (a) -> { 
26             System.out.println("a = " + a); 
27         }; 
28         intConsumer.accept(20); 
29          
30         // 书写技巧:首先定义一个接口函数对象,然后后面跟lambda表达式。 
31         // lambda参数列表根据接口函数的方法参数类型和参数个数。 
32         // lambda的方法体,是否有返回值,根据接口函数的方法是否有返回值。 
33     } 
34  
35 }

发布评论
IT序号网

微信公众号号:IT虾米 (左侧二维码扫一扫)欢迎添加!

Java1.8之Lambda表达式、流Stream学习知识解答
你是第一个吃螃蟹的人
发表评论

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。