zoukankan      html  css  js  c++  java
  • 大数据之路week06--day03(jdk8新特性 Lambda表达式)

    为什么使用Lambda表达式?(做为初学者接触这个新的语法,会很懵逼,说道理,我在接触到这一块的时候,语法规则我看到了也很懵逼,因为这个和逻辑的关系不是很大,但就是作为一种新的语法出现,一时间很难接受。所以,只要我们多加练习,熟悉了就会接受了,记住,要多加练习!!就像你和一个刚刚学习Java的人来说,你和他说100遍地Hello world 的格式,他也不会写,这个需要自己去敲。)

    Lambda是一个匿名函数,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样传递)。使用它可以写出更简介、更灵活的代码。作为一种更为紧凑的代码风格,使Java的语言表达能力得到了提升。

    Lambda表达式:在Java8语言中引入的一种新的语法元素和操作符。这个操作符为 “->” ,该操作符被称为Lambda操作符或箭头操作符。它将Lambda分为两个部分:

      左侧:指定了Lambda表达式需要的参数列表。

      右侧:指定了Lambda体,是抽象方法的实现逻辑,也即Lambda表达式要执行的功能。

    Lambda表达式的本质:接口的具体实现类的实现对象。

    那么接下来介绍Lambda表达式的六种语法格式:

    在介绍学习之前,先看一些例子,感受一下Lambda表达式。还是,要多加练习,慢慢地我们就会习惯。

    在学习Lambda表达式之前,我们学过Compared

     1 Comparator<Integer> com1 = new Comparator<Integer>() {
     2 
     3             @Override
     4             public int compare(Integer o1, Integer o2) {
     5                 return Integer.compare(o1, o2);
     6             }
     7         };
     8 
     9         int compar1 = com1.compare(12, 21);
    10         System.out.println(compar1);

    再将它改为Lambda表达式写法:

    1 Comparator<Integer> com2 =(o1,o2) ->Integer.compare(o1, o2);

    2 int compar2 = com2.compare(41, 21);

    System.out.println("lambda表达式写法:"+compar2); 

    我们会发现很神奇,本来一大段地代码,Lambda表达式一行搞定。

    1、语法格式一:无参,无返回值。

     1 // lambda格式一 无参无返回值的
     2     @Test
     3     public void test1() {
     4         Runnable r = new Runnable() {
     5             @Override
     6             public void run() {
     7                 System.out.println("改之前:  这是lambda格式一修改之前无参无返回值的输出结果");
     8             }
     9         };
    10 
    11         r.run();
    12 
    13         System.out.println("**************************");
    14 
    15         Runnable r1 = () -> {
    16             System.out.println("改之后:  这是lambda格式一修改之后无参无返回值的输出结果");
    17         };
    18 
    19         r1.run();
    20     }

    2、语法格式二:Lambda表达式需要一个参数,但是没有返回值。

     1 // lambda格式一 带参无返回值的
     2     @Test
     3     public void test2() {
     4         Consumer<String> c = new Consumer<String>() {
     5             @Override
     6             public void accept(String s) {
     7                 System.out.println(s);
     8             }
     9         };
    10         c.accept("改之前:  这是lambda格式二修改之前带参无返回值的输出结果");
    11 
    12         System.out.println("************************");
    13 
    14         Consumer<String> c1 = (String s2) -> {
    15             System.out.println(s2);
    16         };
    17         c1.accept("改之后:  这是lambda格式二修改之后带参无返回值的输出结果");
    18     }

    3、语法格式三:数据类型可以省略,因为可由编译器推断得出,称为“类型推断”。

     1 // lambda格式三 类型推断
     2     @Test
     3     public void test3() {
     4         Consumer<String> c1 = (s2) -> {
     5             System.out.println(s2);
     6         };
     7         c1.accept("改之后:  这是lambda格式三对格式二优化类型推断之后带参无返回值的输出结果");
     8     }
     9     
    10     //类型推断举例理解
    11     @Test
    12     public void test4(){
    13         List<String> list = new ArrayList<>();//类型自动推断
    14         int[] arr = {1,2,3};//类型自动推断
    15     }

    4、若Lambda表达式只需要一个参数的时候,参数的小括号可以省略

     1 //格式四 当lambda只需要一个参数的时候,参数小括号可以省略 
     2     @Test
     3     public void test5(){
     4         //1
     5         Consumer<Integer> con = new Consumer<Integer>() {
     6             @Override
     7             public void accept(Integer i) {
     8                 System.out.println("格式四修改之前:"+(i+4));
     9             }
    10         };
    11         con.accept(5);
    12         
    13         System.out.println("**************");
    14         Consumer<Integer> con1 = i -> {
    15             System.out.println("格式四修改之后:"+(i+4));
    16         };
    17         con1.accept(6);
    18         
    19     }

    5、语法格式五:Lambda表达式需要两个或者两个以上的时候,多条执行语句,并且可以有返回值。(小括号不能省略)

     1 //格式五  lambda需要2个或者2个以上的参数 多条执行语句,并且可以有返回值
     2     @Test
     3     public void test6(){
     4         Comparator<Integer> com = new Comparator<Integer>() {
     5             @Override
     6             public int compare(Integer o1, Integer o2) {
     7                 System.out.println(o1);
     8                 System.out.println(o2);
     9                 return o1.compareTo(o2);
    10             }
    11         };
    12         System.out.println(com.compare(12, 21));
    13         
    14         System.out.println("*********************");
    15         Comparator<Integer> com1 = (o1,o2) ->{
    16             System.out.println(o1);
    17             System.out.println(o2);
    18             return o1.compareTo(o2);
    19         };
    20         System.out.println(com1.compare(12, 6));    
    21     }

    6、语法格式六:当Lambda体只有一条语句的时候,return与大括号若有,都可以省略

     1 //格式六  对于lambda体而言,lambda体只有一条语句,return和大括号都可省略
     2     @Test
     3     public void test7(){
     4         Comparator<Integer> com1 = (o1,o2) ->{
     5             return o1.compareTo(o2);
     6         };
     7         System.out.println(com1.compare(6, 6));    
     8         
     9         System.out.println("****************");
    10         Comparator<Integer> com2 = (o1,o2) -> o1.compareTo(o2);
    11         System.out.println(com2.compare(12, 6));    
    12     }

    什么是函数式(Function)接口?

    只包含一个抽象方法的接口,称之为函数式接口。

    你可以通过Lambda表达式来创建该接口的对象,(若Lambda表达式抛出一个受检异常(即:非运行时异常),那么该异常需要在目标接口的抽象方法上进行声明。) @FunctionlInterface 注解

    Java内置的四大核心函数式接口:

    1、Consumer

     1 @Test
     2     public void test1(){
     3         happyTime(500.0, new Consumer<Double>() {
     4 
     5             @Override
     6             public void accept(Double doubled) {
     7                 System.out.println("今天去了一趟天上人间,消费"+doubled);
     8             }
     9         });
    10         
    11         System.out.println("**************");
    12         happyTime(400.0, money -> System.out.println("今天去了一趟天上人间,消费"+money));
    13     }
    14     
    15     public void happyTime(Double money,Consumer<Double> con){
    16         con.accept(money);
    17     }

    2、Supplier

     1 @Test
     2     public void test6(){
     3         Student s1 = new Student();
     4         Function<Student, String> fun = s -> s.getName();
     5         System.out.println(fun.apply(s1));
     6         
     7         
     8     }
     9 
    10 
    11 //学生类
    12 
    13 package com.wyh.方法引用;
    14 
    15 /**
    16 
    17  * 创建时间:2019年12月11日 下午5:22:16
    18 
    19  * 项目名称:practise13_JAVA8新特性
    20 
    21  * @author WYH
    22 
    23  * @version 1.0
    24 
    25  * @since JDK 1.8.0
    26 
    27  * 文件名称:Student.java
    28 
    29  * 类说明:
    30 
    31  */
    32 
    33 public class Student {
    34     private String name = "王友虎";
    35     private int age = 22;
    36     public String getName() {
    37         return name;
    38     }
    39     public void setName(String name) {
    40         this.name = name;
    41     }
    42     public int getAge() {
    43         return age;
    44     }
    45     public void setAge(int age) {
    46         this.age = age;
    47     }
    48     
    49 
    50 }
    51 
    52     

    3、Function

    1 @Test 
    2     public void test4(){//
    3         
    4         //Math类中有个静态方法round() 四舍五入,取整数部分
    5         Function<Double,Long> fun = d -> Math.round(d);
    6         System.out.println(fun.apply(500.25));
    7     }

    4、Predicate

    1 @Test
    2     public void test7(){
    3         Predicate<String> pre = s -> s.equals("abc");
    4         System.out.println(pre.test("abc"));
    5     }

    方法引用

    当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!

    方法引用可以看作是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。

    要求:实现接口的抽象方法的参数列表和返回值类型相同,必须与方法引用的方法参数列表和返回值类型保持一致。(针对于接下来说的情况1和情况2

    格式:使用操作符 “::”将类(或对象)与方法名分割开来

    具体分为如下的三种情况:

      情况1  对象::非静态方法

      情况2  类::静态方法

      情况3  类::非静态方法(较为难理解)

    情况1:

     1 @Test
     2     public void test1(){
     3         Consumer<String> con = s -> System.out.println(s);
     4         con.accept("北京欢迎你");
     5         
     6         System.out.println("方法引用方式一    对象::非静态方法****************");
     7         
     8         PrintStream pin = System.out;
     9         Consumer<String> con1 = pin::println;
    10         con1.accept("这个是方法引用。。");
    11     }
    12     
    13     @Test
    14     public void test2(){
    15         Object obj = new Object();
    16         Supplier<Class> sup = () -> obj.getClass();
    17         System.out.println(sup.get());
    18         
    19         System.out.println("方法引用方式一    对象::非静态方法***********");
    20 
    21         Supplier<Class> sup2 = obj::getClass;
    22         System.out.println(sup2.get());
    23         
    24     }

    情况2:

     1 @Test
     2     public void test3(){
     3         Comparator<Integer> com = (t1,t2) -> Integer.compare(t1,t2);
     4         System.out.println(com.compare(12, 21));
     5         
     6         System.out.println("方法引用方式二    类::静态方法**************");
     7         Comparator<Integer> com1 = Integer::compare;
     8         System.out.println(com1.compare(21, 21));
     9     }
    10     
    11     @Test 
    12     public void test4(){//
    13         
    14         //Math类中有个静态方法round() 四舍五入,取整数部分
    15         Function<Double,Long> fun = d -> Math.round(d);
    16         System.out.println(fun.apply(500.25));
    17         
    18         System.out.println("方法引用方式二    类::静态方法**************************");
    19         Function<Double,Long> fun1 = Math::round;
    20         System.out.println(fun1.apply(500.65));
    21     }

    情况3:

     1 @Test
     2     public void test5(){
     3         Comparator<String> com = (t1,t2) -> t1.compareTo(t2);
     4         System.out.println(com.compare("abc", "cbd"));
     5         
     6         System.out.println("方法引用方式三   类::非静态方法********************");
     7         //如果一个方法有两个参数,调用方法的时候,其中有一个参数去调方法的时候,我们可以将这个参数看作为一个类,然后观察这个参数的数据类型,改变成方法引用如下
     8         Comparator<String> com1 = String::compareTo;
     9         System.out.println(com1.compare("abc", "cbd"));
    10     }
    11     
    12     @Test
    13     public void test6(){
    14         Student s1 = new Student();
    15         Function<Student, String> fun = s -> s.getName();
    16         System.out.println(fun.apply(s1));
    17         
    18         Function<Student, String> fun1 = Student::getName;
    19         System.out.println(fun1.apply(s1));
    20     }
  • 相关阅读:
    Net Core -- 配置Kestrel端口
    NET Core迁移
    NET Core 2.0 微服务跨平台实践
    NET Core 与 Vue.js 服务端渲染
    Varnish 实战
    Hitchhiker 是一款开源的 Restful Api 测试工具
    ABP框架用Dapper实现通过SQL访问数据库
    开源框架总体介绍
    Net Core API网关Ocelot
    Jquery autocomplete插件
  • 原文地址:https://www.cnblogs.com/wyh-study/p/12024907.html
Copyright © 2011-2022 走看看