大数据之路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     }
posted @ 2019-12-11 20:20  Xiaohu_BigData  阅读(438)  评论(0编辑  收藏  举报