第一章 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

浙公网安备 33010602011771号