最近想系统性的学习一下Spring Boot和Spring Cloud,然而在学习SpringBoot的过程中遇到了WebFlux这座大山翻越不过去了,为了能够对Web Flux有个入门级别的了解,学习了晓风轻老师的相关内容,把这段时间对Web Flux的学习历程记录一下:
- 函数式编程和Lambda表达式
- Stream流编程
- reactive响应式流
- webflux开发
本篇文章主要是对函数式编程和lambda表达式的学习做一个简单的笔记,欢迎各位指正。
函数式编程
为什么要用函数式编程?
作为一个Java开发人员,在lambda出现之前,一直使用的是指令式编程,指令式编程关注的点是怎么做,而函数式编程关注的是做什么,无需关注细节。这里面最关键的点就是一个是关注怎么做,而一个关注的是做什么。可能这么说有点抽象,我举个例子说明下,假设我们要从一堆数字里面找出最小的数字,如果用指令式变成怎么做?
public class MinDemo {
public static void main(String[] args) {
int[] nums = {1,2,3,-1,-2,-3};
int min = Integer.MAX_VALUE;
for (int i : nums) {
if(i < min) {
min = i;
}
}
}
}
这段代码对Java程序员来说不算什么,不过我们可以看到这里面写了for循环,for循环里面又定义了一些临时变量,这些就是指令式编程的特点,你想获得一个最小的数,就要关注怎么去做,自己去思考步骤。
回到函数式编程上面来。如果一个不懂code的业务人员让他从一堆数字中找小数字怎么做?没错,财务人员会打开Excecl,然后使用Excel中的min函数,选中相关的单元格就完事儿了。不需要定义一堆变量,不需要再写for循环了,关注的就是要获得最小的数字。那么在Java中怎么用函数式编程呢,还是根据上面的例子改写一下:
public class MinDemo {
public static void main(String[] args) {
int[] nums = {1,2,3,-1,-2,-3};
// IntStream是一个数字流
int min = IntStream.of(nums).min().getAsInt();
System.out.println(min);
}
}
这里面我们在也看不到任何的for循环了,里面最关键的min函数,帮我们搞定了一切,也就是我前面所说的关注做什么,min就是目前要关注的。
这个例子很简单,但是我们可以发散一下,如果说我想从超级多的一堆数字中找到最小的数字,这个时候我们该怎么做呢?在以前的Java中,我们可能要使用多线程来拆分数组,然后分开计算最小值,那么有很多很多的细节需要考虑,但是如果使用函数式编程怎么做,例子如下:
public class MinDemo {
public static void main(String[] args) {
int[] nums = {1,2,3,-1,-2,-3};
// IntStream是一个数字流
int min = IntStream.of(nums).min().parallel().getAsInt();
System.out.println(min);
}
}
什么new Thread都看不见了,一个parellel搞定了一切,这就是函数式编程的强大所在!
lambda表达式
lambda表达式,用晓轻风老师最经典的一句话来说就是,它返回的是一个实现了指定接口的对象实例。什么意思呢,还是例子来说明:
public static void main(String[] args) {
Object target = new Runnable() {
@Override
public void run() {
System.out.println("ok");
}
};
new Thread((Runnable) target).start();
}
想启动一个线程,jdk8之前,需要实现一个Runnable接口,然后new Thread来start,麻烦不?麻烦。那么jdk8之后,我们可以使用lambda表达式来解决这个问题:
public static void main(String[] args) {
// jdk8 lambda
Runnable target = () -> System.out.println("ok");
new Thread(target).start();
}
没错()-> System.out.println("ok")替代了那一大堆什么恶心的override,public void run之类的东西。
->的左边表示输入参数,右边是表达式。我们这里只有一个(),表示输入参数为空,确实,public void run方法本来就没有输入参数。右边的东西就是run方法中的逻辑