后来又看了一下这本身,感觉过于学术+偏向于数据结构。
所以感觉不如 《java8 函数式编程》适合学习。
序言
学习 java 函数式编程的目的主要有 2 个:
(1)运用下 jdk8
(2)重新理解这种编程思想
实际上很多东西都要反复学些。
准备工作
你可以同时阅读下列内容:
后来又看了一下这本身,感觉过于学术+偏向于数据结构。
所以感觉不如 《java8 函数式编程》适合学习。
学习 java 函数式编程的目的主要有 2 个:
(1)运用下 jdk8
(2)重新理解这种编程思想
实际上很多东西都要反复学些。
你可以同时阅读下列内容:
理解现实世界中的函数
在 Java 中表示函数
使用lambda
使用高阶函数
使用柯里化函数
用函数式接口编程
为了理解函数式编程是如何工作的, 我们会使用一些函数式库提供的函数式组件,还有Java 8 标准库里可用的少许组件。
不仅如此, 我们还会关注如何构建它们,而不仅仅是如何使用。
lambda 被用于接收特定接口的地方, Java 正是以此来决定调用哪个方法的。
Java 并不对命名加以限制,有些语言则不然。
唯一的限制是所用的接口必须要明确,这通常意味着它应该有且仅有一个抽象方法。(实际上会更复杂一些,因为有些方法不算在内。)
这样的接口就是SAM (single abstract method, 单一抽象方法)类型,被称为函数式接口 (functional interface)。
请注意 lambda 井不仅仅用于函数,在标准Java 8 中可以使用许多函数式接口,虽然它们并不都与函数相关。
在第1 章中,你用了我称之为函数的东西,但实际上它们是方法。
方法是一种在传统的Java 里在某种程度上表示函数的方式。
一个方法可以是函数式的,只要它满足纯函数的要求:
它不能修改函数外的任何东西。外部观测不到内部的任何变化。
它不能修改自己的参数。
它不能抛出错误或异常。
它必须返回一个值。
只要调用它的参数相同,结果也必须相同。
控制结构是命令式编程的主要组成部分。命令式的 Java 程序员都不会相信无须使用 if···else switch .. ·case for, while do 循环即可编写程序。这些结构是命令式编程的本质。但在接下来的章节中,你将学习如何编写绝对没有控制结构的函数式程序。在本节中,你不会那么激进一一我们只关注以更加函数式的风格来使用传统的控制结构。
纯函数式的方法除了返回 1 个值以外不能做任何其他事情。它们不能改变外围作用域里的对象或引用。方法返回的值只能取决于它的参数,尽管方法可以读取外围作用域里的数据。在这种情况下,数据被认为是隐式参数
在命令式编程中,控制结构定义了作用域,它们一般在作用域内工作,也就意味着它们具有作用。这个作用可能仅在控件结构的作用域内可见,也可能在外围作用域内可见。控制结构还可以访问外围作用域来取值。
如果某个对象在被创建后其状态就不能被修改,那么这个对象就称为不可变对象。
线程安全性是不可变对象的固有属性之一,它们的不变性条件是由构造函数创建的,只要它们的状态不改变,那么这些不变性条件就能得以维持。
不可变对象一定是线程安全的。
当满足以下条件时,对象才是不可变的:
对象创建以后其状态就不能修改。
对象的所有域都是 final 类型(当然像不可变String类型的域并不需要声明为final)。
对象是正确创建的(在对象的创建期间,this引用没有逸出)。
有状态就是有数据存储功能。有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,是非线程安全的。在不同方法调用间不保留任何状态。
无状态就是一次操作,不能保存数据。无状态对象(Stateless Bean),就是没有实例变量的对象.不能保存数据,是不变类,是线程安全的。
线程安全类的一个很好的例子是java servlet,它没有字段和引用,没有其他类的字段等等。它们是无状态(stateless)的。
public class StatelessFactorizer implements Servlet {
public void service(ServletRequest req, ServletResponse resp) {
BigInteger i = extractFromRequest(req);
BigInteger[] factors = factor(i);
encodeIntoResponse(resp, factors);
}
}