Java学习笔记——Lambda表达式

函数式编程思想概述

在数学中,函数就是有输⼊量、输出量的⼀套计算⽅案,也就是“拿什么东⻄做什么事情”。相对
⽽⾔,⾯向对象过分强调“必须通过对象的形式来做事情”,⽽函数式思想则尽量忽略⾯向对象的
复杂语法 – 强调做什么,⽽不是以什么形式做。
⾯向对象的思想:
做⼀件事情,找⼀个能解决这个事情的对象,调⽤对象的⽅法,完成事情。
函数式编程思想:
只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程。

冗余的Runnable代码

传统写法

public class Demo01Runnable {
 public static void main(String[] args) {
 // 匿名内部类
 Runnable task = new Runnable() {
 @Override
 public void run() { // 覆盖重写抽象⽅法
 System.out.println("多线程任务执⾏!");
 }
 };
 new Thread(task).start(); // 启动线程
 }
}

代码分析

对于 Runnable 的匿名内部类⽤法,可以分析出⼏点内容:
Thread 类需要 Runnable 接⼝作为参数,其中的抽象 run ⽅法是⽤来指定线程任务内容的核
⼼;
为了指定 run 的⽅法体,不得不需要 Runnable 接⼝的实现类;
为了省去定义⼀个 RunnableImpl 实现类的麻烦,不得不使⽤匿名内部类;
必须覆盖重写抽象 run ⽅法,所以⽅法名称、⽅法参数、⽅法返回值不得不再写⼀遍,且不
能写错;
⽽实际上,似乎只有⽅法体才是关键所在。

体验Lambda的更优写法

public class Demo02LambdaRunnable {
 public static void main(String[] args) {
 new Thread(() -> System.out.println("多线程任务执⾏!")).start(); // 启动线
程
 }
}

这段代码和刚才的执⾏效果是完全⼀样的,可以在1.8或更⾼的编译级别下通过。从代码的语义
中可以看出:我们启动了⼀个线程,⽽线程任务的内容以⼀种更加简洁的形式被指定。
不再有“不得不创建接⼝对象”的束缚,不再有“抽象⽅法覆盖重写”的负担,就是这么简单!

回顾匿名内部类

在上例中,核⼼代码其实只是如下所示的内容:

() -> System.out.println("多线程任务执⾏!")

使⽤实现类

要启动⼀个线程,需要创建⼀个 Thread 类的对象并调⽤ start ⽅法。⽽为了指定线程执⾏的内
容,需要调⽤ Thread 类的构造⽅法:
public Thread(Runnable target)

为了获取 Runnable 接⼝的实现对象,可以为该接⼝定义⼀个实现类 RunnableImpl :

public class RunnableImpl implements Runnable {
 @Override
 public void run() {
 System.out.println("多线程任务执⾏!");
 }
}

然后创建该实现类的对象作为 Thread 类的构造参数:

public class Demo03ThreadInitParam {
 public static void main(String[] args) {
 Runnable task = new RunnableImpl();
 new Thread(task).start();
 }
}

使⽤匿名内部类

这个 RunnableImpl 类只是为了实现 Runnable 接⼝⽽存在的,⽽且仅被使⽤了唯⼀⼀次,所以使
⽤匿名内部类的语法即可省去该类的单独定义,即匿名内部类:

public class Demo04ThreadNameless {
 public static void main(String[] args) {
 new Thread(new Runnable() {
 @Override
 public void run() {
 System.out.println("多线程任务执⾏!");
 }
 }).start();
 }
}

匿名内部类的好处与弊端

⼀⽅⾯,匿名内部类可以帮我们省去实现类的定义;另⼀⽅⾯,匿名内部类的语法 – 确实太复
杂了!

语义分析

仔细分析该代码中的语义, Runnable 接⼝只有⼀个 run ⽅法的定义:
public abstract void run();
即制定了⼀种做事情的⽅案(其实就是⼀个函数):
⽆参数:不需要任何条件即可执⾏该⽅案。
⽆返回值:该⽅案不产⽣任何结果。
代码块(⽅法体):该⽅案的具体执⾏步骤。
同样的语义体现在 Lambda 语法中,要更加简单:

() -> System.out.println("多线程任务执⾏!")

前⾯的⼀对⼩括号即 run ⽅法的参数(⽆),代表不需要任何条件;
中间的⼀个箭头代表将前⾯的参数传递给后⾯的代码;
后⾯的输出语句即业务逻辑代码。

** Lambda标准格式**

(参数类型 参数名称) -> { 代码语句 }

格式说明:

⼩括号内的语法与传统⽅法参数列表⼀致:⽆参数则留空;多个参数则⽤逗号分隔。
-> 是新引⼊的语法格式,代表指向动作。
⼤括号内的语法与传统⽅法体要求基本⼀致。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值