1. 为什么要使用函数式编程
关注点不同: 命令式编程关注的是怎样做,告诉程序怎样做,才能达到一个功能 而函数式是关注做什么,不需要告诉怎么做,不需要关注实现的细节,告诉它要实现什么功能即可
举例:在一堆数字里面找到最小的值,两种实现方式如下
/** * 什么是函数式编程 */public class WhyUseLambda { private static final Logger log = LoggerFactory.getLogger(WhyUseLambda.class); public static void main(String[] args) { int[] nums = {22, 44, -30, 90, -400, 10}; old(nums); lambda(nums); }// 命令式编程 public static void old(int[] nums){ int min = Integer.MAX_VALUE; for (int num : nums) { if (num < min) { min = num; } } log.info("old method min: {}", min); }// 函数式 public static void lambda(int[] nums){ int min = IntStream.of(nums).min().getAsInt(); log.info("lambda method min: {}", min); }}复制代码
如此应该可以理解一下了,命令式编程需要我们告诉程序如何实现这个功能,注重实现的细节,函数式则不关注这个实现的细节,只要最终结果。
拓展一下刚才的例子,如果数据量很大,那么按照之前的命令式编程代码,消耗的时间就会很多,然后我们就得利用线程池和二分法等方法去优化我们的代码,这里面的代码都是我们要实现的,而函数式就很便捷了,直接利用 parallel 方法快速优化,代码如下:
int min = IntStream.of(nums).parallel().min().getAsInt();复制代码
还有在代码简洁明了方面的对比:
public static void threadContrast(){ new Thread(new Runnable() { @Override public void run() { log.info(" old method ok"); } }).start(); new Thread(() -> log.info("lambda method ok")).start();}复制代码
对比两种写法,你会发现函数式编程更优雅。也许你刚开始不怎么习惯,但是用多了,你会发现,函数式编程是真的好用!
2. lambda 初接触
修改一下上面使用线程的代码如下:
public static void threadContrast1(){ Runnable target = new Runnable() { @Override public void run() { log.info(" old method ok"); } }; new Thread(target).start(); Runnable target2 = () -> log.info("lambda method ok"); new Thread(target2).start();}复制代码
可以看出, 这个 lambda 返回的是一个接口的实例。
再修改一下代码:
public static void threadContrast2(){ Object target = new Runnable() { @Override public void run() { log.info(" old method ok"); } }; new Thread((Runnable)target).start(); Object target2 = (Runnable) () -> log.info("lambda method ok"); new Thread((Runnable)target2).start();}复制代码
如此可以看出,lambda 表达式要告诉它返回实现的接口类型。
简单总结: lambda 表达式返回了一个实现指定接口的实例
代码地址: https://github.com/hmilyos/lambda-demo.git复制代码