13.超越java8-函数式的思考

不打扰是莪最后的温柔 提交于 2020-01-30 02:59:21

文章是个人阅读《Java8实战》过程中的重点摘抄,可能晦涩,没有示例代码,后续会补充总结完善。


本章内容

  • 为什么要进行函数式编程
  • 什么是函数式编程
  • 声明式编程以及引用透明性
  • 编写函数式Java的准则
  • 迭代和递归

核心问题

1.函数式编程的定义是什么?为什么要采用函数式编程?
2.函数式编程的特性是什么?
3.无副作用指的是什么?声明式指的又是什么?
4.纯粹的函数式编程和java中函数式编程的不同之处是什么?java函数式编程的准则是什么?
5.什么是函数式编程的引用透明性?

概述

本章介绍什么是函数式编程,以及一些相关的术语。我们首先会探究函数式编程的概念,比如副作用、不变性、声明式编程、引用透明,并将他们和java8的实践结合。


13.1 实现和维护系统

我们日常的系统维护工作,很多情况是代码遭遇一些无法预期的值,引发系统异常导致功能不可用。函数式编程提出了“无副作用”和“不变性”,对于解决这一难题有很大帮助。

13.1.1 共享的可变数据

共享可变数据的问题主要是,当存在多个类同时共享一个可变对象时(并行),我们很难知道哪个类真正拥有这个对象。由于使用了可变的共享数据结构,我们很难跟踪程序各个部分发生的变化。

如果一个方法不修改他内嵌类的状态,也不修改其他对象的状态,使用return返回计算结果,我们称其为无副作用的。更确切的讲,造成副作用的原因往往是函数的效果已经超出了函数自身的范畴。

13.1.2 声明式编程

我们一般在做编程时,通常使用“如何做”的思维方式。他的特点与底层的词汇很接近,不如赋值、条件分支、循环等。另一种时更关注“做什么”,就像StreamAPI一样。这种方式把最终实现的细节留给了函数库。并且他的巨大优势是,语句更像是问题的陈述。

13.1.3 为什么要采用函数式编程

函数式编程实践了声明式编程(描述做什么,由系统来实现)和无副作用计算,这两个思想可以帮助我们更容易的构建和维护系统。比外,构造操作和传递行为的语言特性让我们的程序便于阅读。


13.2 什么是函数式编程

函数式编程就是使用函数进行编程的方式。那什么是函数呢?在函数式编程的上下文中,一个“函数”对应一个数学函数:他接受零个或多个参数,生成一个或多个结果,并且不会由任何副作用。尤其是,使用同样的参数调用数学函数,它所返回的结果一定是相同的。这种类型的函数和java编程语言中的函数之间的区别是非常重要的。我们吧这种成为纯粹的函数式编程,后者为函数式编程。

13.2.1 函数式java编程

在实际的编程中,我们是无法以纯粹的函数来完成一个程序的。比如javaIO中的Scanner.nextLine就有副作用,从文件中读取一行,通常两次的调用结果是不同的。

不过我们还是可以在程序的核心组件编写接近纯粹函数式的实现。如果要编写函数式的程序,首先确保代码客户端无法察觉代码的副作用。假设这样一个函数或者方法,它没有副作用,进入方法体执行时会对一个字段的值加一,退出方法体之前会对该字段减一。对一个单线程的程序而言,这个方法是没有副作用的,可以看作函数式的实现。换个角度而言,如果该方法会同时被多个线程并发调用——那么这个方法就不能称之为函数式的实现了。当然,你可以用加锁的方式对方法的方法体进行封装,掩盖这一问题,你甚至可以再次声称该方法符合函数式的规定。但是,这样做之后,你就失去了在你的多核处理器的两个核上并发执行两个方法调用的能力。它的副作用对程序可能是不可见的,不过对于程序员你而言是可见的,因为程序运行的速度变慢了!

我们的准则是,被称为“函数式”的函数或方法只能修改本地变量,并且他引用的对象都是不可修改的对象,或者这些对象对其他对象是不可见的

被成为函数式,函数或方法不能抛出异常。但是从实际操作角度来说,我们可以在本地局部的使用异常,避免通过接口暴露给其他方法,这种方式即取得了函数式的优点,可不会让代码过度膨胀。

最后,作为函数式的程序,我们的函数或方法调用的库方法如果有副作用,必须设法隐藏他们的非函数行为,否则就不能调用

符合以上规定的方法,通常会使用注释标注,我们可以将其作为参数传递给并发流进行处理。

13.2.2 引用透明性

如果一个函数只要传递同样的参数值,总是返回同样的结果,那这个函数就是引用透明的。例如String.replace方法就是引用透明的。换句话说,函数无论在何处、何时调用,如果使用同样的输入总能持续地得到相同的结果,就具备了函数式的特征。

13.3 递归和迭代

》》》

13.4 小节

  • 从长远看,减少共享的可变数据结构能帮助你降低维护和调试程序的代价。
  • 函数式编程支持无副作用的方法和声明式编程。
  • 函数式方法可以由它的输入参数及输出结果进行判断。
  • 如果一个函数使用相同的参数值调用,总是返回相同的结果,那么它是引用透明的。采用递归可以取得迭代式的结构,比如while循环。
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!