java自学教程|www.konglongmei.com

作者: 123456806
查看: 28|回复: 0

more +社区更新Forums

more +随机图赏Gallery

疯狂Java讲义(第4版) PDF 电子书 百度云 网盘下载疯狂Java讲义(第4版) PDF 电子书 百度云 网盘下载
价值825元 牛客算法通关课程视频教程 第六期 百度云 网盘下载价值825元 牛客算法通关课程视频教程 第六期 百度云 网盘下载
Spring 5核心原理与30个类手写实战 PDF 电子书 百度云 网盘下载Spring 5核心原理与30个类手写实战 PDF 电子书 百度云 网盘下载
Spring 5核心原理与30个类手写实战+Spring Boot编程思想核心篇pdfSpring 5核心原理与30个类手写实战+Spring Boot编程思想核心篇pdf
Spring Boot编程思想核心篇+Spring 5核心原理与30个类手写实战pdfSpring Boot编程思想核心篇+Spring 5核心原理与30个类手写实战pdf
java电子书]微服务架构设计模式 PDF 电子书 百度云 网盘下载java电子书]微服务架构设计模式 PDF 电子书 百度云 网盘下载

[技术知识] Lambda表达式---Day27

[技术知识] Lambda表达式---Day27

[复制链接]
123456806 | 显示全部楼层 发表于: 3 天前
123456806 发表于: 3 天前 | 显示全部楼层 |阅读模式
查看: 28|回复: 0

你还没有注册,无法下载本站所有资源,请立即注册!

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
函数式编程思想概述
  在数学中,函数就是有输入量、输出量的一套计算方案,也就是“拿什么东西做什么事情”。相对而言,面向对象过 分强调“必须通过对象的形式来做事情”,而函数式思想则尽量忽略面向对象的复杂语法——强调做什么,而不是以 什么形式做。
  面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
  函数式编程思想: 只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程
冗余的Runnable代码
  传统写法:当需要启动一个线程去完成任务时,通常会通过 java.lang.Runnable 接口来定义任务内容,并使用 java.lang.Thread 类来启动该线程
  1. 1 package demosummary.lambda; 2  3 public class RunnableDemo1 { 4     public static void main(String[] args) { 5         //匿名内部类 6         Runnable task = new Runnable() { 7             @Override 8             public void run() { 9                 System.out.println("多线程任务执行");10             }11         };12         new Thread(task).start();//启动线程13     }14 }
复制代码
  对上述代码分析:
    1.Thread 类需要 Runnable 接口作为参数,其中的抽象 run 方法是用来指定线程任务内容的核心
    2.为了指定 run 的方法体,不得不需要 Runnable 接口的实现类
    3.为了省去定义一个 RunnableImpl 实现类的麻烦,不得不使用匿名内部类;
    4.必须覆盖重写抽象 run 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错;
    5.而实际上,似乎只有方法体才是关键所在
lambda更优的写法
  1. 1 package demosummary.lambda; 2  3 /** 4  * Lambda写法 5  */ 6 public class LambdaDemo1 { 7     public static void main(String[] args) { 8         new Thread(() -> System.out.println("多线程任务执行")).start();//启动线程 9     }10 }
复制代码
  以上代码和上一个代码是同样的执行效果,lambda写法需要在1.8以上的编译才能通过
回顾匿名内部类
  1.使用实现类
    要启动一个线程,需要创建一个 Thread 类的对象并调用 start 方法。而为了指定线程执行的内容,需要调用 Thread 类的构造方法:public Thread(Runnable target)
      为了获取 Runnable 接口的实现对象,可以为该接口定义一个实现类 RunnableImpl :
  1. 1 package demosummary.lambda;2 3 public class RunnableImpl implements Runnable{4     @Override5     public void run() {6         System.out.println("多线程任务执行");7     }8 }
复制代码
    然后创建该实现类的对象作为 Thread 类的构造参数:
  1. 1 package demosummary.lambda; 2  3 public class RunnableImplTest { 4     public static void main(String[] args) { 5         //创建RunnableImpl对象 6         RunnableImpl ri = new RunnableImpl(); 7         //启动线程 8         new Thread(ri).start(); 9     }10 }
复制代码
  2.使用匿名内部类
    这个 RunnableImpl 类只是为了实现 Runnable 接口而存在的,而且仅被使用了唯一一次,所以使用匿名内部类的 语法即可省去该类的单独定义,即匿名内部类:
  1. 1 package demosummary.lambda; 2  3 /** 4  * 使用匿名内部类 5  */ 6 public class RunnableImplInit { 7     public static void main(String[] args) { 8         new Thread(new Runnable() { 9             @Override10             public void run() {11                 System.out.println("多线程任务执行");12             }13         }).start();14     }15 }
复制代码
  对上述匿名内部类方法分析
    仔细分析该代码中的语义, Runnable 接口只有一个 run 方法的定义:public abstract void run();
    无参数:不需要任何条件即可执行该方案。
    无返回值:该方案不产生任何结果。
    代码块(方法体):该方案的具体执行步骤
  而使用lambda语法要更加简单:
    () ‐> System.out.println("多线程任务执行!")
      前面的一对小括号即 run 方法的参数(无),代表不需要任何条件;
      中间的一个箭头代表将前面的参数传递给后面的代码;
      后面的输出语句即业务逻辑代码。
  匿名内部类的好处与弊端
    一方面,匿名内部类可以帮我们省去实现类的定义;另一方面,匿名内部类的语法——确实太复杂了
Lambda表达式的标准格式
  Lambda省去面向对象的条条框框,格式由3个部分组成:
    1.一些参数 2.一个箭头 3.一段代码
  Lambda表达式的标准格式为:(参数类型 参数名称) ‐> { 代码语句 }
  格式说明:
    1.小括号内的语法与传统方法参数列表一致:无参数则留空;
    2.多个参数则用逗号分隔。 -> 是新引入的语法格式,代表指向动作。
    3.大括号内的语法与传统方法体要求基本一致。
Lambda省略格式
  省略规则:
    1. 小括号内参数的类型可以省略;
    2. 如果小括号内有且仅有一个参,则小括号可以省略;
    3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号
Lambda的使用前提
  Lambda的语法非常简洁,完全没有面向对象复杂的束缚。但是使用时有几个问题需要特别注意
    1. 使用Lambda必须具有接口,且要求接口中有且仅有一个抽象方法。 无论是JDK内置的 Runnable 、 Comparator 接口还是自定义的接口,只有当接口中的抽象方法存在且唯一 时,才可以使用Lambda。
    2. 使用Lambda必须具有上下文推断。 也就是方法的参数或局部变量类型必须为Lambda对应的接口类型,才能使用Lambda作为该接口的实例。
    备注:有且仅有一个抽象方法的接口,称为“函数式接口”。
使用lambda标准格式(无参无返回)
  给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:
  1. 1 package demosummary.lambda;2 3 /**4  * 给定一个厨子 Cook 接口,内含唯一的抽象方法 makeFood ,且无参数、无返回值。如下:5  */6 public interface Cook {7     void makeFood();8 }
复制代码
  在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样:
  1. 1 package demosummary.lambda; 2  3 /** 4  * 在下面的代码中,请使用Lambda的标准格式调用 invokeCook 方法,打印输出“吃饭啦!”字样: 5  */ 6 public class InvokeCook { 7     public static void main(String[] args) { 8 //        invokeCook(() -> { 9 //            System.out.println("吃饭了");10 //        });11         12         //省略格式13         invokeCook(() -> System.out.println("吃饭了"));14     }15 16     private static void invokeCook(Cook cook) {17         cook.makeFood();18     }19 }
复制代码
  备注:小括号代表 Cook 接口 makeFood 抽象方法的参数为空,大括号代表 makeFood 的方法体。
使用Lambda标准格式(有参有返回)
  给定一个计算器 Calculator 接口,内含抽象方法 calc 可以将两个int数字相加得到和值:
  1. 1 package demosummary.lambda;2 3 public interface Calculator {4     int cal(int a, int b);5 }
复制代码
  在下面的代码中,请使用Lambda的标准格式调用 invokeCalc 方法,完成120和130的相加计算:
  1. 1 package demosummary.lambda; 2  3 public class invokeCal { 4     public static void main(String[] args) { 5 //        invokeCal(120,130,(int a , int b) -> { 6 //            return a + b; 7 //        }); 8  9         //省略格式10         invokeCal(120,130,(int a , int b) -> a + b);11     }12 13     public static void invokeCal(int a , int b , Calculator calculator){14         int result = calculator.cal(a, b);15         System.out.println("输出结果:"+result);16     }17 }
复制代码
Lambda的参数和返回值
  需求:     1.使用数组存储多个Person对象     2.对数组中的Person对象使用Arrays的sort方法通过年龄进行升序排序
  1. 1 package demosummary.lambda; 2  3 public class Person { 4     private String name; 5     private int age; 6  7     public Person() { 8     } 9 10     public Person(String name, int age) {11         this.name = name;12         this.age = age;13     }14 15     public String getName() {16         return name;17     }18 19     public void setName(String name) {20         this.name = name;21     }22 23     public int getAge() {24         return age;25     }26 27     public void setAge(int age) {28         this.age = age;29     }30 31     @Override32     public String toString() {33         return "Person{" +34                 "name='" + name + '\'' +35                 ", age=" + age +36                 '}';37     }38 }
复制代码
  1. 1 package demosummary.lambda; 2  3 import java.util.Arrays; 4  5 public class LambdaComparator { 6     public static void main(String[] args) { 7         Person[] array = { 8                 new Person("古力娜扎",22), 9                 new Person("迪丽热巴",21),10                 new Person("欧阳娜娜",19)11         };12 13 //        Arrays.sort(array,(Person a, Person b)->{14 //            return a.getAge() - b.getAge();15 //        });16 17         //省略格式18         Arrays.sort(array,(Person a, Person b) -> a.getAge() - b.getAge());19 20         for (Person person : array) {21             System.out.println(person);22         }23     }24 }
复制代码



鲁班 Java架构师VIP课程一期共89G视频教程 luban it教程下载:http://www.77cxw.com/download/78
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|网站地图|java自学教程|www.konglongmei.com

GMT+8, 2019-12-6 10:44 , Processed in 0.148689 second(s), 47 queries .

快速回复 返回顶部 返回列表