zoukankan      html  css  js  c++  java
  • Java1.8之Lambda表达式

    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 }
  • 相关阅读:
    CodeForces 492C Vanya and Exams (贪心)
    CodeForces 492A Vanya and Cubes
    如何设置 Windows 默认命令行窗口大小和缓冲区大小
    [MySQL] Data too long for column 'title' at row 1
    [转] Hibernate不能自动建表解决办法(hibernate.hbm2ddl.auto) (tables doesn't exist)
    CodeForces 489D Unbearable Controversy of Being (不知咋分类 思维题吧)
    Autofac官方文档翻译--二、解析服务--1解析参数传递
    Autofac官方文档翻译--一、注册组件--4组件扫描
    Autofac官方文档翻译--一、注册组件--3属性和方法注入
    Autofac官方文档翻译--一、注册组件--2传递注册参数
  • 原文地址:https://www.cnblogs.com/biehongli/p/14242482.html
Copyright © 2011-2022 走看看