1.创建一个新的线程,指定线程要执行的任务

public static void main(String[] args) {// 开启一个新的线程new Thread(new Runnable() {@Overridepublic void run() {System.out.println("新线程中执行的代码 : "+Thread.currentThread().getName());}}).start();System.out.println("主线程中的代码:" + Thread.currentThread().getName());}

1.1代码分析

1. Thread类需要一个Runnable接口作为参数,其中的抽象方法run方法是用来指定线程任务内容的核心
2. 为了指定run方法体,不得不需要Runnable的实现类
3. 为了省去定义一个Runnable 的实现类,不得不使用匿名内部类
4. 必须覆盖重写抽象的run方法,所有的方法名称,方法参数,方法返回值不得不都重写一遍,而且不能出错,
5. 而实际上,我们只在乎方法体中的代码

1.2代码优化

new Thread(() -> { System.out.println("新线程Lambda表达式..." +Thread.currentThread().getName()); }).start();

2.Lambda表达式的优点:简化了匿名内部类的使用,语法更加简单。

匿名内部类语法冗余,体验了Lambda表达式后,发现Lambda表达式是简化匿名内部类的一种方式。

3. Lambda的语法规则

Lambda省去了面向对象的条条框框,Lambda的标准格式由3个部分组成:

(参数类型 参数名称) -> {
    代码体;
}

3.1格式说明:

- (参数类型 参数名称):参数列表
- {代码体;} :方法体
- -> : 箭头,分割参数列表和方法体

4.Lambda练习

有参且有返回值得Lambda表达式案例

创建一个Person对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person {private String name;private Integer age;private Integer height;}

然后我们在List集合中保存多个Person对象,然后对这些对象做根据age排序操作

  public static void main(String[] args) {List<Person> list = new ArrayList<>();list.add(new Person("周杰伦",33,175));list.add(new Person("刘德华",43,185));list.add(new Person("周星驰",38,177));list.add(new Person("郭富城",23,170));Collections.sort(list, new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge()-o2.getAge();}});for (Person person : list) {System.out.println(person);}}

我们发现在sort方法的第二个参数是一个Comparator接口的匿名内部类,且执行的方法有参数和返回值,那么我们可以改写为Lambda表达式

 public static void main(String[] args) {List<Person> list = new ArrayList<>();list.add(new Person("周杰伦",33,175));list.add(new Person("刘德华",43,185));list.add(new Person("周星驰",38,177));list.add(new Person("郭富城",23,170));/*Collections.sort(list, new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {return o1.getAge()-o2.getAge();}});for (Person person : list) {System.out.println(person);}*/System.out.println("------");Collections.sort(list,(Person o1,Person o2) -> {return o1.getAge() - o2.getAge();});for (Person person : list) {System.out.println(person);}}

输出结果

Person(name=郭富城, age=23, height=170)
Person(name=周杰伦, age=33, height=175)
Person(name=周星驰, age=38, height=177)
Person(name=刘德华, age=43, height=185)

5.@FunctionalInterface注解

/*** @FunctionalInterface*    这是一个标志注解,被该注解修饰的接口只能声明一个抽象方法*/
@FunctionalInterface
public interface UserService {void show();}

6.Lambda表达式的原理

写的有Lambda表达式的class文件,我们通过XJad查看报错。这时我们可以通过JDK自带的一个工具:javap 对字节码进行反汇编操作。

javap -c -p 文件名.class

-c:表示对代码进行反汇编
-p:显示所有的类和成员

反汇编的结果:

E:\workspace\OpenClassWorkSpace\JDK8Demo\target\classes\com\bobo\jdk\lambda>javap -c -p Demo03Lambda.class
Compiled from "Demo03Lambda.java"
public class com.bobo.jdk.lambda.Demo03Lambda {public com.bobo.jdk.lambda.Demo03Lambda();Code:0: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnpublic static void main(java.lang.String[]);Code:0: invokedynamic #2,  0              // InvokeDynamic #0:show:()Lcom/bobo/jdk/lambda/service/UserService;5: invokestatic  #3                  // Method goShow:(Lcom/bobo/jdk/lambda/service/UserService;)V8: returnpublic static void goShow(com.bobo.jdk.lambda.service.UserService);Code:0: aload_01: invokeinterface #4,  1            // InterfaceMethod com/bobo/jdk/lambda/service/UserService.show:()V6: returnprivate static void lambda$main$0();Code:0: getstatic     #5                  // Field java/lang/System.out:Ljava/io/PrintStream;3: ldc           #6                  // String Lambda show 方法执行了...5: invokevirtual #7                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V8: return
}

在这个反编译的源码中我们看到了一个静态方法 lambda$main$0(),这个方法里面做了什么事情呢?我们通过debug的方式来查看下:

上面的效果可以理解为如下:

public class Demo03Lambda {public static void main(String[] args) {....}private static void lambda$main$0();System.out.println("Lambda show 方法执行了...");}

为了更加直观的理解这个内容,我们可以在运行的时候添加 -Djdk.internal.lambda.dumpProxyClasses, 加上这个参数会将内部class码输出到一个文件中

java -Djdk.internal.lambda.dumpProxyClasses 要运行的包名.类名

E:\workspace\OpenClassWorkSpace\JDK8Demo\target\classes>java -Djdk.internal.lambda.dumpProxyClasses com.bobo.jdk.lambda.Demo03Lambda
Lambda show 方法执行了...

反编译后的内容:

可以看到这个匿名的内部类实现了UserService接口,并重写了show()方法。在show方法中调用了Demo03Lambda.lambda$main$0(),也就是调用了Lambda中的内容。

小结:

匿名内部类在编译的时候会产生一个class文件。

Lambda表达式在程序运行的时候会形成一个类。

1. 在类中新增了一个方法,这个方法的方法体就是Lambda表达式中的代码
2. 还会形成一个匿名内部类,实现接口,重写抽象方法
3. 在接口中重写方法会调用新生成的方法

7.Lambda表达式的省略写法

在lambda表达式的标准写法基础上,可以使用省略写法的规则为:

1. 小括号内的参数类型可以省略
2. 如果小括号内有且仅有一个参数,则小括号可以省略
3. 如果大括号内有且仅有一个语句,可以同时省略大括号,return 关键字及语句分号。

public class Demo05Lambda {public static void main(String[] args) {goStudent((String name,Integer age)->{return name+age+" 6666 ...";});// 省略写法goStudent((name,age)-> name+age+" 6666 ...");System.out.println("------");goOrder((String name)->{System.out.println("--->" + name);return 666;});// 省略写法goOrder(name -> {System.out.println("--->" + name);return 666;});goOrder(name ->  666);}public static void goStudent(StudentService studentService){studentService.show("张三",22);}public static void goOrder(OrderService orderService){orderService.show("李四");}

8.Lambda表达式的使用前提

Lambda表达式的语法是非常简洁的,但是Lambda表达式不是随便使用的,使用时有几个条件要特别注意

1. 方法的参数或局部变量类型必须为接口才能使用Lambda
2. 接口中有且仅有一个抽象方法(@FunctionalInterface)

9.Lambda和匿名内部类的对比

Lambda和匿名内部类的对比

1. 所需类型不一样
   - 匿名内部类的类型可以是 类,抽象类,接口
   - Lambda表达式需要的类型必须是接口

2. 抽象方法的数量不一样
   - 匿名内部类所需的接口中的抽象方法的数量是随意的
   - Lambda表达式所需的接口中只能有一个抽象方法

3. 实现原理不一样
   - 匿名内部类是在编译后形成一个class
   - Lambda表达式是在程序运行的时候动态生成class

lamdba表达式的使用相关推荐

  1. Java8 Lamdba表达式 002

    本篇将讲述lamdba表达式的排序,本例包括一个Player对象的集合[稍后定义],通过每一个player的分数高低对列表的player进行排序.类定义001例如以下 public class Sor ...

  2. 一个简单案例,5 分钟看懂 Java Lamdba 表达式

    JDK8引入了一个新玩意,叫做lamdba(那么大)的表达式,说得神乎其神,说真的,这玩意吧,并不难,但是要讲清楚吧,也不是太容易的事情. 从匿名内部类开始说起 老实交代,直接来讲lamdba表达式还 ...

  3. Java lamdba表达式基础教程

    一.lamdba表达式基础知识 1.lamdba基本知识 Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性. Lambda 允许把函数作为一个方法的参数(函数作为参数传递 ...

  4. JAVA8实战 -- Lamdba表达式

    JAVA8实战 文章目录 JAVA8实战 前言 一.JAVA8的核心和优势是什么 二.Lambda表达式 1.函数式编程 -- 将代码传递给方法(将方法作为参数传递给另外一个代码) 2.Lambda表 ...

  5. java lamdba表达式效率_java8新特性Lambda表达式为什么运行效率低

    Lambda表达式为什么运行效率低 准备 我为什么说Lambda表达式运行效率低. 先准备一个list: 先用Lambda表达式的方式来循环一下这个list: 运行时间大概为110ms 再用普通方式来 ...

  6. java streamhandler_java中的Lamdba表达式和Stream

    基于JDK 1.8 1.循环: // 以前的循环方式 for (String player : players) { System.out.print(player + "; ") ...

  7. C#语法之匿名函数和Lambda表达式

    上一篇博客主要是对委托和事件做了一小结,这篇是在上一篇博客的基础上对匿名函数和Lambda表达式小结.还是接着上一篇说起,在上一篇中也说了委托是一种数据结构,主要是解决让函数作为参数的问题.在使用委托 ...

  8. C# Lambda表达式

    "Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量.它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型, ...

  9. 表达式树 php,Linux_LINQ学习笔记:表达式树,构建查询表达式 本节中, 我们 - phpStudy...

    构建查询表达式 本节中, 我们假设我们拥有一个这样的实体类: 1: [Table] public partial class Product 2: 3: { 4: 5: [Column(IsPrima ...

最新文章

  1. LeCun论战Markus:AI是否需要类似人类的认知能力?
  2. 安卓9全局圆角_三星S9+升级最新系统ONE UI体验,安卓9.0带来哪些惊喜?
  3. Blogengine-BlogRoll的两个bug
  4. 升级造成eclipse插件失效
  5. boost::copy相关的测试程序
  6. 合并外部知识库-学习资料
  7. 巴斯卡三角形 and 數字位移
  8. 二叉树的中序遍历非递归方法(算法导论第三版12.1-3)
  9. 360浏览器兼容问题
  10. HTML元素显示与隐藏
  11. 华为数通笔记-QOS
  12. 树莓派4支持多大tf卡_树莓派入门指南(Raspberry Pi)
  13. java面试问题与心得
  14. MySQL高级语句(一)---常用查询、视图、null值
  15. Perl-列表和数组2
  16. element-ui 响应式布局
  17. 【优秀论文解读】UV-SLAM: Unconstrained Line-based SLAM Using Vanishing Points for Structural Mapping
  18. 力扣(LeetCode)——编译、提交和注释快捷键
  19. 短信发送一次显示两条之谜
  20. windows系统安装配置mysql8,并设置远程访问

热门文章

  1. Android电子书翻页效果
  2. Mina State machine状态机讲解
  3. 接口与接口、接口与类之间的关系
  4. 【图结构专题】有向图
  5. consistent read一致性读,DDL DML DCL
  6. 夜来风雨声,MapReduce知多少?
  7. 数据使用要谨慎——不良数据带来严重后果
  8. 多媒体制作技术心得体会_交互式多媒体课件制作的一点心得体会
  9. jenkins 配置git
  10. 一文回顾区块链修订WTO电子商务禁令的影响