您的位置 首页 java

Java8方法引用和Lambda表达式实例源码+笔记分享

前言

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

1、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 }  
Java8方法引用和Lambda表达式实例源码+笔记分享

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、@ function alInterface注解

此注解是函数式接口注解,所谓的函数式接口,当然首先是一个接口,然后就是在这个接口里面只能有一个抽象方法。这种类型的接口也称为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 }  

文章来源:智云一二三科技

文章标题:Java8方法引用和Lambda表达式实例源码+笔记分享

文章地址:https://www.zhihuclub.com/198406.shtml

关于作者: 智云科技

热门文章

网站地图