Java8新特性之Lambda表达式的应用与理解

1 基本使用

package com.example.shardingjdbcsimple;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

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

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("新线程执行的代码:" + Thread.currentThread().getName());
            }
        }).start();

        /*Lambda表达式的优点: 简化了匿名内部类的使用,语法更加简单。
        匿名内部类语法冗余,体验了Lambda表达式后,发现Lambda表达式是简化置名内部类的一种方式。*/
        new Thread(() -> {
            System.out.println("新线程Lambda表达式..." + Thread.currentThread().getName());
        }).start();

        System.out.println("主线程中的代码:" + Thread.currentThread().getName());

        /**
         * 语法规则:
         * (参数类型 参数名称) -> {}
         * 格式说明: (参数类型 参数名称) : 参数列表
         * {代码体}:方法体
         * -> : 分割参数列表和方法体
         */

        /**
         * 无参数无返回值的练习1:
         */
        goShow(new UserService() {
            @Override
            public void show() {
                System.out.println("show方法执行了");
            }
        });
        goShow(() ->{
            System.out.println("Lambda: show方法执行了");
        });
        /**
         * 有参有返回值的练习2:
         */
        ArrayList<Person> personList = new ArrayList<>();
        personList.add(new Person("zhoujielun", 35, 100));
        personList.add(new Person("liudehua", 60, 110));
        personList.add(new Person("zhouxingchi", 70, 120));
        personList.add(new Person("goufucheng", 45, 180));
        Collections.sort(personList, new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge() - o2.getAge();
            }
        });
        Collections.sort(personList, (o1, o2) -> {
            return o1.getAge() - o2.getAge();
        });
        System.out.println(personList);
    }
    public static void goShow(UserService userService) {
        userService.show();
    }
}

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

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

2 原理解析

在这里插入图片描述
Lambda表达式的原理是什么呢?
在这里插入图片描述
我们通过jdk自带的反编译工具查看:

javap -c -p 文件名.class

在这里插入图片描述
在这个反编译的源码中,我们看到了一个静态方法lambda$main$0();方法体中的代码是在lambda$main$0()中执行的;

匿名内部类在编译的时候会生成一个class文件,Lambda表达式在程序运行的时候会形成一个类。
1.在类中新增了一个方法, 这个方法的方法体就是Lambda表达式中的代码
2.还会形成一个国名内部类,实现接口,重写抽象方法
3.在接口中重写方法会调用新生成的方法

3 省略写法

在lambda表达式的标准写法基础上,可以使用省略的规则为:
1.小括号内的参数类型可以省略
2.如果小括号内有且仅有一个参数,则小括号可以省略
3.如果大括号内有且仅有一个语句,可以同时省略大括号,return 关键字及语句分号。

package com.example.shardingjdbcsimple;

public class MainT {
    public static void main(String[] args) {
        goStudent((String name, Integer age) -> {
            return name + age + " 666";
        });
        goStudent((name, age) -> name + age + " 666");

        goOrder((String name) -> {
            System.out.println(name);
            return 999;
        });
        goOrder(name -> 666);
    }
    public static void goStudent(StudentService studentService) {
        studentService.show("zhangsan", 11);
    }
    public static void goOrder(OrderService orderService) {
        orderService.show("lisi");
    }
}
interface StudentService {
    String show(String name, Integer age);
}

interface OrderService {
    Integer show(String name);
}

4 Lambda的使用前提

Lambda表达式的潘法是非常简洁的,但是ambda表达式不是随便使用的,使用时有几个条件要特别注意:
1.方法的参数或局部变量类型必须为按口才能使用Lambda
2.按口中有且仅有一个抽象方法(@FunctionalInterface)

5 Lambda与匿名内部类的对比

Lambda和匿名内部类的对比:
1.所需类型不一样
1.重名内部类的类型可以是类,抽象类,接口
2. Lambda表达式需要的类型必须是接口
2.抽象方法的数量不一-样
1.置名内部类所需的接口中的抽象方法的数量是随意的
2. Lambda表达式所需的接口中只能有一个抽象方法
3.实现原理不-样
1.医名内部类是在编泽后形成一个class
2. Lambda表达式是在程序运行的时候动态生成class

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值