最后更新时间:2020年10月23日10点16分
目录
一、函数式编程思想概述
1、概述
在数学中,函数就是输入量、输出量的一套计算方案,也就是“拿什么东西,做什么事情”。相对而言,面向对象过分强调“必须通过对象的形式来做事情”,而函数式编程则尽量忽略面向对象的复杂语法——强调做什么,而不是以什么形式做。
2、面向对象的思想
做一件事情,找到能做这个事情的对象,调用对象的方法,完成事情;
3、函数式编程思想
只要能获取结果,谁去做的,怎么做的都不重要(结果重要,过程不重要);
二、冗余的代码案例(Runnable)
RunnableImpl类:
package study.lambda;
public class RunnableImpl implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==========");
}
}
RunnableImplTest类:
package study.lambda;
public class RunnableImplTest {
public static void main(String[] args) {
//1、一般写法
RunnableImpl runnable = new RunnableImpl();
Thread thread = new Thread(runnable);
thread.start();
//2、简化写法
Runnable runnable1 = new Runnable(){
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==========");
}
};
new Thread(runnable1).start();
//3、再简化
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==========");
}
}).start();
//由上可知,无论怎么简化都是很麻烦的,实际有用的代码只有一行
}
}
由上可知,无论怎么简化都是很麻烦的,实际有用的代码只有一行。
三、编程思想转换和体验Lambda
1、我们真正的目的是什么:关注做什么,而不是怎么做
将run方法内部的代码块传递给Thread类;
2、代码演示(比较):
匿名内部类实现方式:
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"==========");
}
}).start();
Lambda表达式实现方式:
new Thread(()->{
System.out.println(Thread.currentThread().getName()+"==========");
}).start();
//而且在当只有一行输出语句的时候可以省略大括号和分号,如下:
new Thread(()->System.out.println(Thread.currentThread().getName()+"==========")).start();
四、Lambda表达式的标准格式
1、3部分组成
一些参数,一个箭头,一段代码;
2、标准格式及其说明
(参数列表) -> { 代码语句 }
():接口中抽象方法的参数列表;
->:将参数传递给方法体的意思;
{}:重写的抽象方法的方法体;
五、无参无返回值案例
接口:
package study.lambda;
public interface Cook {
void make();
}
测试类:
package study.lambda;
public class Test {
public static void main(String[] args) {
cook1(() -> System.out.println("做饭啦"));
}
//写一个方法调用接口的方法
private static void cook1(Cook cook){
cook.make();
}
}
六、有参有返回值案例
代码示例:
常规来讲,用方法调用接口内方法时,将其他参数放在接口前
接口:
package study.lambda;
public interface Cook {
String make(String string);
}
测试类:
package study.lambda;
public class Test {
public static void main(String[] args) {
String string = cook1("我就是参数啦",(String string1) -> {
return string1+"======这就是返回值你信不信!"
});
System.out.println(string);//我就是参数啦======这就是返回值你信不信!
}
//写一个方法调用接口的方法
private static String cook1(String string,Cook cook){
return cook.make(string);
}
}
七、Lambda表达式省略式
1、Lambda表达式
可推导,可省略;
凡是可以通过上下文推到出来的内容,都可以省略;
2、可省略的内容
①(参数列表):括号中参数列表的数据类型可以省略不写;
②(参数列表):若括号中只有一个参数,那么括号也可以省略不写;
③{一些代码}:如果代码只有一行,({},return,分号;)可以省略不写,要省略3个必须一起省略;
3、测试类省略之后
package study.lambda;
public class Test {
public static void main(String[] args) {
String string = cook1("我就是参数啦",string1 -> string1+"======这就是返回值你信不信!");
System.out.println(string);//我就是参数啦======这就是返回值你信不信!
}
//写一个方法调用接口的方法
private static String cook1(String string,Cook cook){
return cook.make(string);
}
}
4、注意
①使用Lambda抽象类必须是“有且仅有一个抽象方法”(这样的接口也成为了函数式接口);
②使用Lambda必须具有上下文推断;
八、Lambda发展由来
1、代码简化历程
普通类实现接口——静态内部类实现接口——局部内部类实现接口——匿名内部类实现接口——Lambda表达式实现接口;
2、代码实现
package com.zb.thread;
public class Main {
public static void main(String[] args) {
//4、局部内部类实现接口
class Pig implements Action{
@Override
public void go() {
System.out.println("猪行走!");
}
}
//常规实现
Action action = new Cat();
action.go();
//简化:静态内部类
action = new Dog();
action.go();
//再简化:局部内部类实现接口
action = new Pig();
action.go();
//再简化:匿名内部类实现接口
action = new Action() {
@Override
public void go() {
System.out.println("(匿名内部类)不知道是谁在走!");
}
};
action.go();
//再简化:Lambda表达式实现接口
//我们可以明白,最重要的信息就是参数、方法
action = () -> System.out.println("(Lambda表达式)不知道是谁在走!");
action.go();
}
//3、静态内部类实现接口
static class Dog implements Action{
@Override
public void go() {
System.out.println("狗行走!");
}
}
}
//1、创建一个函数式接口(只有一个方法的接口)
interface Action{
void go();
}
//2、普通类实现接口
class Cat implements Action {
@Override
public void go() {
System.out.println("猫咪走路!");
}
}
3、运行结果
猫咪走路!
狗行走!
猪行走!
(匿名内部类)不知道是谁在走!
(Lambda表达式)不知道是谁在走!