前言
最近都没什么时间给自己充电,不过想了想还是要继续学习的,所以想着开始写一期博客关于:以前用过但是又没学懂的知识
,可以称之为薛定谔的知识
,就是我看得懂,也会用,但是为什么要这么用,什么时候这么用?我不知道
这一节的第一讲就从最近用的比较多的Lambda表达式开始吧
,本文仅当为入门学习,如有遗漏还请指出。
Lambda表达式
什么是Lambda表达式
Lambda表达式
是自Java 8 版本引入的一个重要特性
,也可以说是最重要的一个特性,它提供了一种更简洁、更直接的方式来表示功能接口(即只包含一个抽象方法的接口)的匿名实现
。Lambda表达式允许你以一种更接近数学中函数概念的方式编写代码
,使得Java编程更加灵活和表达力更强。
注意上面的:它提供了一种更简洁、更直接的方式来表示功能接口(即只包含一个抽象方法的接口)的匿名实现(省略了方法名的实现)
。
这一句可以简单缩短为:提供了只有一个方法接口的匿名实现方式
,首先它是接口的实现方式,什么实现方式呢?匿名实现。
还是没看太懂?没事,我们接着往下看
初识Lambda表达式
我们先看一个Lambda表达式的简单使用,先认识认识它们,然后再慢慢摸索。
下面我们来看一个常见的Lambda表达式的使用,以及它们的格式。
Lambda表达式的简单使用
以下是一个使用Lambda表达式实现自定义接口的示例
首先创建一个只有一个抽象方法的的接口
。
@FunctionalInterface//用于表示这是一个函数式接口的注解 即该接口中只有一个方法 关于函数后续会提到
public interface DemoLambdaInterface {
int operate(int a , int b);//两个数的简单操作
}
那我们再来看看如何使用Lambda表达式实现该接口
public class Test {
public static void main(String[] args) {
//接口中方法的匿名实现
DemoLambdaInterface demoLambdaInterface = (a , b) -> a + b;
//调用跟常规接口方法调用没有区别
System.out.println("使用Lambda表达式匿名实现的接口调用结果为:" + demoLambdaInterface.operate(1, 2));
}
}
Lambda表达式格式分析
相信大家对于上述的代码,还是看不懂,你确定这一段是Java代码?(a , b) -> a + b;
其实将这段代码:DemoLambdaInterface demoLambdaInterface = (a , b) -> a + b;
补全你就知道了
补全之后就是以下这样的
//接口中方法的匿名实现
DemoLambdaInterface demoLambdaInterface = (a , b) -> {
return a + b;
};
结合我们接口中的定义
@FunctionalInterface//用于表示这是一个函数式接口的注解 即该接口中只有一个方法 关于函数后续会提到
public interface DemoLambdaInterface {
int operate(int a , int b);//两个数的简单操作
}
看出来什么没有,没错就是那个! 接口的实现嘛,不过我们一般写实现都是带了方法名的
int operate(int a , int b) {
return a + b;
}
现在我们来分析上述代码,
(a , b)表示接口方法的入参,但是没有类型,比如int ,String
->
是一个特殊的语法符号,被称为箭头操作符
或者Lambda操作符
,起到参数与方法体分割的作用
其后的{}
中的内容就是方法体的具体实现内容
了。
而在Lambda表达式中单行代码是可以省略{}和return
的,也就成了上面的:
DemoLambdaInterface demoLambdaInterface = (a , b) -> a + b;
如果方法的参数为空,那括号里可以什么都不写了
与传统接口方法实现的比较
如果按照常规的方法
,来实现接口方法,我们一般怎么写?
首先肯定是创建一个实现类
DemoLambdaInterfaceImpl:
public class DemoLambdaInterfaceImpl implements DemoLambdaInterface {
//实现接口方法
int operate(int a , int b) {
return a + b;
}
}
然后使用的时候再通过创建实现类对象去调用:
DemoLambdaInterface dli = new DemoLambdaInterfaceImpl();
dli.operate(1 , 2);
与上面的Lambda表达式相比,谁简洁一目了然。
理解Lambda表达式
我们先来做点课前准备工作,将以下几部分学习完再理解Lambda表达式
就很简单了。以下几部分同样是Lambda表达式的重要特性。
函数式编程
Lambda表达式
可以说是实现函数式编程的一个重要工具
。那么什么是函数式编程呢?
函数式编程是一种编程范式
,强调程序构建在不可变数据和纯函数之上
。
不可变数据好理解,关键是后面的纯函数什么?
纯函数
是指对于相同的输入总是产生相同的输出
,并且没有‘副作用’
,这里的副作用是:不改变外部状态或依赖外部状态
。
注意这两点:相同的输入总有相同的输出
,不改变外部状态或依赖外部状态
。
要快速理解这两句话,我们要从相反的角度
看:相同的输入得到不同的输出,改变外部状态或者依赖外部状态的就不是函数式编程
。
非纯函数实例
来看以下非纯函数的代码:
public class Test {
static int gamePeopleCount = 0;
public static void main(String[] args) {
String demoStr = "小游戏玩家: ";
int a = addGamePeopleCount("小明");
System.out.println("当前游戏人数:" + a);
addGame(demoStr , "小明");
}
public static int addGamePeopleCount(String name) {
System.out.println(name + " 加入了游戏。");
//每次返回的结果不一样
gamePeopleCount+=1;
return gamePeopleCount;
}
public static void addGame(String demoStr , String name) {
//修改了demoStr的值 也就改变了外部状态
demoStr = demoStr +" "+ name;
System.out.println(demoStr);
}
}
纯函数示例
再看一个纯函数的示例
:
public int add(int a , int b) {
return a + b;
}
在纯函数中,很明显可以看出上述两个特征:相同的输入总有相同的输出
,不改变外部状态或依赖外部状态
。
函数式编程在Lambda表达式中的体现
上面的代码就是
//接口中方法的匿名实现
DemoLambdaInterface demoLambdaInterface = (a , b) -> a + b<