发布时间:2023-02-14 文章分类:编程知识 投稿人:赵颖 字号: 默认 | | 超大 打印

读Java实战(第二版)笔记09_函数式的思考

1.规则

1.1.传递参数,返回结果

1.1.1.异常和中断都不算返回结果

1.2.减少共享的可变数据结构能帮助你降低维护和调试程序的代价

2.耦合性

2.1.软件系统中各组件之间是否相互独立

3.内聚性

3.1.系统的各相关部分之间如何协作

4.无状态的行为

4.1.流水线中的函数不会由于需要等待从另一个方法中读取变量,或者由于需要写入的变量同时有另一个方法正在写而发生中断

4.2.无须担心锁引起的各种问题

4.3.充分发掘系统的并发能力

5.副作用

5.1.函数的效果已经超出了函数自身的范畴

5.2.除了构造器内的初始化操作,对类中数据结构的任何修改,包括字段的赋值操作

5.3.抛出一个异常

5.4.进行输入/输出操作

6.无副作用

6.1.纯粹的

6.2.如果一个方法既不修改它内嵌类的状态,也不修改其他对象的状态,使用return返回所有的计算结果

6.3.如果构成系统的各个组件都能遵守这一原则,该系统就能在完全无锁的情况下,使用多核的并发机制,因为任何一个方法都不会对其他的方法造成干扰

6.4.了解程序中哪些部分是相互独立的

7.不可变对象

7.1.一旦完成初始化就不会被任何方法修改状态

7.2.一旦一个不可变对象初始化完毕,它永远不会进入到一个无法预期的状态

7.3.线程安全的

8.声明式编程

8.1.关注要做什么

8.2.更加接近问题陈述

9.命令式编程

9.1.指令和计算机底层的词汇非常相近

9.2.专注于如何实现

10.引用透明性

10.1.没有可感知的副作用

10.1.1.不改变对调用者可见的变量

10.1.2.不抛出异常

10.1.3.不进行I/O

10.2.如果一个函数只要传递同样的参数值,总是返回同样的结果,那这个函数就是引用透明的

11.记忆化

11.1.缓存

11.2.对代价昂贵或者需长时间计算才能得到结果的变量值的优化

11.2.1.通过保存机制而不是重复计算

12.函数式编程

12.1.程序有一定的副作用

12.1.1.该副作用不会被其他的调用者感知

12.1.1.1.如果没人能感知的话,函数式也允许进行变更,这意味着可以修改局部变量

12.1.2.调用者不需要知道,或者完全不在意这些副作用

12.2.如果有副作用

12.2.1.必须设法隐藏它们的非函数式行为

12.2.2.否则就不能调用这些方法

12.2.3.需要确保它们对数据结构的任何修改对于调用者都是不可见的,可以通过首次复制,或者捕获任何可能抛出的异常实现这一目的

12.3.函数式的函数或方法都只能修改本地变量

12.3.1.所有的字段都为final类型

12.3.2.所有的引用类型字段都指向不可变对象

12.3.3.引用的对象都应该是不可修改的对象

12.4.选择使用引用透明的函数

12.5.不应该抛出任何异常

12.5.1.选择在本地局部地使用异常,避免通过接口将结果暴露给其他方法,这种方式既取得了函数式的优点,又不会过度膨胀代码

13.局部函数式(partial function)

13.1.大多数的输入值都返回一个确定的结果

13.2.对另一些输入值,它的结果是未定义的,甚至不返回任何结果

13.2.1.除法,如果除法的第二操作数是0

13.2.2.开平方运算,开平方的参数为负数

13.2.3.使用Optional类型

14.纯粹的函数式编程

14.1.不提供像while或者for这样的迭代结构

14.1.1.这种结构经常隐藏着陷阱,诱使你修改对象

15.递归recursion

15.1.函数式编程特别推崇的一种技术

15.2.培养你思考要“做什么”的编程风格

15.3.每个程序都能使用无须修改的递归重写,通过这种方式避免使用迭代

15.3.1.采用递归可以取代迭代式的结构,比如while循环

15.3.2.使用递归,可以消除每步都需更新的迭代变量

15.4.递归的形式通常效率都更差一些

15.4.1.因为每次执行递归方法调用都会在调用栈上创建一个新的栈帧,用于保存每个方法调用的状态(即它需要进行的乘法运算),这个操作会一直指导程序运行直到结束

15.4.2.很容易遭遇StackOverflowError异常

15.5.大多数时候编程的效率要比细微的执行时间差异重要得多

15.6.尾调优化(tail-call optimization)

15.6.1.编写方法的一个迭代定义,不过迭代调用发生在函数的最后

15.6.1.1.调用发生在尾部

15.6.2.Java不支持这种优化

15.6.3.Scala、Groovy和Kotlin,支持对这种形式的递归的优化

15.6.3.1.最终实现的效果和迭代不相上下(它们的运行速度几乎是相同的)