学 Java8 函数式编程

Posted JAVA早餐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学 Java8 函数式编程相关的知识,希望对你有一定的参考价值。

闲聊

Java 一直以来是使用最广泛的编程语言之一,有很多人担心在为她的未来担心。但随着 Java8 的横空出世和即将发布的 Java9 让 Java 迎来了第二春。Java8 最大的改变是引入了函数式编程,Java9 引入了模块化编程。函数式和模块化编程 拥有非常美好的未来,很多优秀的编程语言如 javascript 和 Scala 都拥有这些特性。

我们为什么要学习 Java8 的函数式编程?

  • 为了编写出更加简单、干净、易读的代码。

  • 为了简化集合的操作。

  • 为了简单地使用并行计算提高程序的性能。

什么是函数式编程

函数式编程的核心是:在思考问题时,使用不可变值和函数,函数对一个值进行处理,映射成另一个值。

面向对象编程是对数据进行抽象,而函数式编程是对行为进行抽象。

当看到上面的有点晦涩难懂的概念时,我相信大家和我一样都是一脸蒙逼。先别急,其实我们都有接触过函数式编程。可能你们会有疑问,不是 Java8 才引入函数式编程么,我们之前也没使用过 Java8 。为了消除大家的疑惑,我们先看看清单一中的代码。

清单一

学 Java8 函数式编程(一)

在清单一中我创建了一个类 Calculater 和一个接口 IIntegerMath 。在 Calculater 的 main 方法中,我调用了 Calculater 的静态方法 add 。在调用 add 方法时,我 new 了一个实现 IIntegerMath 接口的匿名内部类对象作为 add 方法的第参数。在匿名内部内中实现了具体的 operation 方法。

其实在给 add 方法传参数时,我们真正需要的是一个行为,也就是 IIntergerMath 接口中的 operaton 方法。这就是函数式编程要做的事,对行为进行抽象。「ps: 在这里我对函数式编程是对行为进行抽象这个概念解释的还不是很清楚,我相信你们通过具体的代码会有更加深刻清晰地理解。」

我相信大家有注意到, main 方法中的变量 a 和 b 被定义成了 final 类型的。因为如果在匿名内部类只能调用外部类的 final 变量。在 operation 方法中我们将 a 和 b 映射成了另一个值。在调用 add 方法时,我们在用函数式编程解决问题,我们在 add 方法中传入了一个方法(函数) operation ,而 operation 将不可变值 a 和 b 映射成了另一个值。

「ps: 我不知道我是否已将函数式编程的概念表达清楚了,如果大家有更好的见解,可以分享出来。」

初识 Lambda 表达式

我相信大家已经发现,我用清单一中的代码解释什么是函数式编程显得非常牵强。因为清单一中的代码是 Java8 之前的写法,属于命令式代码。何为命令式代码?我是这么理解的,在写一段关键代码的同时要附加上很多样板式代码,这些样板式代码让真正有价值的部分黯然失色。在清单一中,你们会发现在调用 add 方法式,我们需要的仅仅是 operation 方法中的 return a + b,而其他的代码显得特别多余,这些多余的代码就属于样板式代码。

命令式风格的代码并不能让 Java 拥有函数式编程的特性。所以在 Java 8 引入了 Lambda 表达式。在本文中,我只会将清单一中的代码用 Lambda 表达式(见清单二)再重写一遍,将两种风格的代码呈现出来做一个对比,我会在之后的博客中详细介绍 Lambda 表达式。

清单二

大家看到清单二中的代码是不是有大吃一惊,我就用一行代码做了清单一中 n 多行代码才能完成的事。这就是 Lambda 表达式的神奇之处,清单二中的 Lambda 表达式 () -> a + b 能够清晰地诠释函数式编程的核心思想。你们可能还是不理解我为什么要这么说,没事,我会在之后的博客中和大家一起深入地学习和探索 Lambda 表达式。


java海量视频资源免费获取、java最新资讯、新闻每日更新。

请长按图片,关注下方二维码

亲们,所有资源全部免费,视频均来源于网络,若发现个别资源失效,请及时联系早餐君,早餐君发现后会立即修改连接。你们的支持使我们坚持的动力!



以上是关于学 Java8 函数式编程的主要内容,如果未能解决你的问题,请参考以下文章

《Java8实战》读书笔记12:函数式编程

初识函数式编程与函数式接口

java8函数式编程实例

当java8实现了函数式编程

Java8自定义函数式编程接口

Java8函数式接口编程lambda表达式FunctionalInterface注解SupplierConsumerPredicateFunction函数式接口