第一章 JDK8新特性1之Lambda表达式_更简洁的代码

前言

  最近在看一个nodeJS写的web项目,其中FRP(函数响应式编程)和异步非阻塞简直毁三观了(虽然long long ago写Android时了解异步任务AsyncTask,知道耗时操作不能放在main thread之类的)。斗智斗勇数日无果,决定先回归老本行,看看java里的FRP是怎么回事,再以毒攻毒搞定nodejs。所以文章中会穿插java和js的代码,但只要有OOP基础,相信都能看明白,毕竟FRP是一种通用型编程思想,不局限于某种语言。

  首先来看下学习路线:(1) JDK8_lambda表达式,(2) JDK8_四大函数接口,(3)JDK8_Stream流,(4)JDK9_Reactive Stream响应式流,(5) Reactor,(6)Flux(以微服务框架SpringBoot2.0 的WebFlux为例)。

1.1 由lambda表达式引入函数式编程

  Java8坐上神坛时,nodejs已因NIO和近j2EE10倍的并发量初露锋芒。有点慌,赶紧先把函数式编程安排上。函数式编程,其实是相对于命令式编程的另一种编程范式,网上有很多不同的解释,简单可以理解为:一个函数可以接受一个函数作为参数,并可以返回一个函数。两者不同之处在于:命令式编程关注做什么,函数式编程关注怎么做。

看一个js的例子:

 1     //参数是函数的例子
 2     function add(a,b){
 3         return a + b;
 4     }
 5     
 6     function sub(a,b){
 7         return a - b;
 8     }
 9     
10     function calculator(num1,num2,operator){
11         return operator(num1,num2);
12     }
13     
14     alert("5-3=" + calculator(5,3,sub));

或者使用箭头函数(js的lambda):

1 function calculator(num1,num2,operator){
2         return operator(num1,num2);
3     }
4     
5 alert("5-3=" + calculator(5,3,(x,y) => {return x-y}));

Lambda表达式的语法
基本语法:
(parameters) -> expression

(parameters) ->{ statements; }

lambda表达式本质是一个匿名函数(语法糖),之所以java到jdk8才有lambda,可能因为java既不像弱类型语言,方法(Function)属于对象;也不像C++有函数指针,java的方法不允许直接接受一个函数作为参数,那要实现函数式编程怎么办呢?用接口包装一个函数声明,再用这个接口作为函数参数。

来看一个例子:

 1 public class LambdaTester {
 2     public static void main(String[] args) {
 3         System.out.println("main function...");
 4         testLambda();
 5     }
 6 
 7     //以接口作为参数
 8     private int operate(int x,int y,IOperation ioperation){
 9         return ioperation.operate(x,y);
10     }
11 
12     //测试lambda函数
13     public static void testLambda() {
14 
15         LambdaTester tester = new LambdaTester();
16         System.out.println("Lambda test");
17         IOperation addOperation = (x, y) -> {return x+y;}; //返回实现该接口的对象实例,return可省
18         IOperation subOperation = (x, y) -> x-y; //省略return的情况
19         IOperation printParams = (x,y) -> {  //多行代码用{}括起
20             System.out.println("x=" + x + ",y=" + y);
21             return 0;
22         };
23 
24         System.out.println("1:2+4=" + tester.operate(2,4,addOperation));
25         System.out.println("2:3-2=" + tester.operate(3,2,subOperation));
26         System.out.println("3:" + tester.operate(6,8,printParams));
27 
28     }
29 
30 }

函数式接口定义如下:

1 //java函数不能直接以函数作为参数,所以要通过接口封装,该接口中有且只有一个需要被实现的函数
2 @FunctionalInterface
3 public interface IOperation {
4     public int operate(int x,int y);
5 }

输出结果:

main function...
Lambda test
1:2+4=6
2:3-2=1
x=6,y=8
3:0

 

1.2 JDK8接口新特性

1、函数接口中有且只有一个需要被实现的方法。可以在接口上加注解 @FunctionalInterface,表示这是一个函数式接口,编译时会校验该接口中是否只有一个函数。一个接口只做一件事的设计思路被称为单一责任制

2、接口中可以有默认方法 default,该方法有默认实现:

 1 public class LambdaTester {
 2     public static void main(String[] args) {
 3         System.out.println("main function...");
 4         testDefault();
 5     }
 6 
 7     public static void testDefault(){
 8         IOperation iOperation = (x,y) -> {return 0;};   
 9         System.out.println(iOperation.addDefault(7,8));
10     }
11 }

接口定义:

 1 @FunctionalInterface
 2 public interface IOperation {
 3     public int operate(int x,int y);
 4 
 5     //默认方法
 6     default int addDefault(int x,int y){
 7         return x+y;
 8     }
 9 
10 }

输出:

main function...
15

 

Reference

title:Java 能抵挡住 JavaScript 的进攻吗?link:https://mp.weixin.qq.com/s/EPHjHvHdtPWVLFvHdVUnhQ

title:Java响应式编程 Springboot WebFlux基础与实战 link:https://coding.imooc.com/class/209.html

posted @ 2019-02-15 16:30  唐空空  阅读(203)  评论(0)    收藏  举报