Skip to content

Commit ef786cb

Browse files
authored
Merge pull request lingcoder#213 from xiangflight/master
revision[13] 13章结束
2 parents 4c6f47d + b5dfc60 commit ef786cb

File tree

1 file changed

+9
-10
lines changed

1 file changed

+9
-10
lines changed

docs/book/13-Functional-Programming.md

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1274,7 +1274,7 @@ public class Closure9 {
12741274

12751275
### 作为闭包的内部类
12761276

1277-
我们可以复制我们的例子使用匿名内部类:
1277+
我们可以使用匿名内部类重写之前的例子:
12781278

12791279
```java
12801280
// functional/AnonymousClosure.java
@@ -1300,7 +1300,7 @@ public class AnonymousClosure {
13001300
## 函数组合
13011301

13021302

1303-
函数组合(Function Composition)意为“多个函数组合成新函数”。它通常是函数式编程的基本组成部分。在前面的 `TransformFunction.java` 类中,有一个使用 `andThen()` 的函数组合示例。 `java.util.function` 包里包含支持函数组合的一些接口方法 [^7]
1303+
函数组合(Function Composition)意为“多个函数组合成新函数”。它通常是函数式编程的基本组成部分。在前面的 `TransformFunction.java` 类中,有一个使用 `andThen()` 的函数组合示例。一些 `java.util.function` 接口中包含支持函数组合的方法 [^7]
13041304

13051305
| 组合方法 | 支持接口 |
13061306
| :----- | :----- |
@@ -1343,7 +1343,7 @@ _fter _ll _mbul_nces
13431343

13441344
这里我们重点看正在创建的新函数 `f4`。它调用 `apply()` 的方式与常规几乎无异[^8]
13451345

1346-
`f1` 获得字符串时,它已经被`f2` 剥离了前三个字符。这是因为对 `compose(f2)`的调用意味着在 `f1` 之前调用 `f2`
1346+
`f1` 获得字符串时,它已经被`f2` 剥离了前三个字符。这是因为 `compose(f2)` 表示 `f2` 的调用发生在 `f1` 之前
13471347

13481348
下例是 `Predicate` 的逻辑运算演示.代码示例:
13491349

@@ -1376,14 +1376,13 @@ foobaz
13761376

13771377
`p4` 获取到了所有断言并组合成一个更复杂的断言。解读:如果字符串中不包含 `bar` 且长度小于 5,或者它包含 `foo` ,则结果为 `true`
13781378

1379-
正因它产生如此清晰的语法,我在主方法中采用了一些小技巧,并借用了下一章的内容。首先,我创建一个流的字符串对象集合,然后将每个对象传递给 `filter()` 操作。 `filter()` 使用 `p4` 的断言来确定对象的去留。最后我们使用 `forEach()` `println` 方法打印出留下来的对象
1379+
正因它产生如此清晰的语法,我在主方法中采用了一些小技巧,并借用了下一章的内容。首先,我创建了一个字符串对象的流,然后将每个对象传递给 `filter()` 操作。 `filter()` 使用 `p4` 的断言来确定对象的去留。最后我们使用 `forEach()` `println` 方法引用应用在每个留存的对象上
13801380

13811381
从输出结果我们可以看到 `p4` 的工作流程:任何带有 `foo` 的东西都会留下,即使它的长度大于 5。 `fongopuckey` 因长度超出和不包含 `bar` 而被丢弃。
13821382

13831383
<!-- Currying and Partial Evaluation -->
13841384
## 柯里化和部分求值
13851385

1386-
13871386
[柯里化](https://en.wikipedia.org/wiki/Currying)(Currying)的名称来自于其发明者之一 *Haskell Curry*。他可能是计算机领域唯一名字被命名重要概念的人(另外就是 Haskell 编程语言)。 柯里化意为:将一个多参数的函数,转换为一系列单参数函数。
13881387

13891388
```java
@@ -1458,7 +1457,7 @@ public class Curry3Args {
14581457
Hi Ho Hup
14591458
```
14601459

1461-
对于每个级别的箭头级联(Arrow-cascading),你可以围绕类型声明包装成另一个函数
1460+
对于每个级别的箭头级联(Arrow-cascading),你在类型声明中包裹了另一个 **Function**
14621461

14631462
处理基本类型和装箱时,请使用适当的 **Function** 接口:
14641463

@@ -1473,7 +1472,7 @@ public class CurriedIntAdd {
14731472
curriedIntAdd = a -> b -> a + b;
14741473
IntUnaryOperator add4 = curriedIntAdd.apply(4);
14751474
System.out.println(add4.applyAsInt(5));
1476-
}
1475+
}
14771476
}
14781477
```
14791478

@@ -1483,13 +1482,13 @@ public class CurriedIntAdd {
14831482
9
14841483
```
14851484

1486-
更多柯里化示例,可搜索互联网。通常这些是 Java 以外的语言,理解它们的基本概念,就应该很容易翻译
1485+
可以在互联网上找到更多的柯里化示例。通常它们是用 Java 之外的语言实现的,但如果理解了柯里化的基本概念,你可以很轻松地用 Java 实现它们
14871486

14881487
<!-- Pure Functional Programming -->
14891488
## 纯函数式编程
14901489

14911490

1492-
即使没有函数式支持,像 C 这样的基础语言,也可以按照一定的原则编写纯函数程序。Java 8 让函数式编程更简单,不过我们要确保一切是 `final` 的,同时你的所有方法和函数没有副作用。因为 Java 在本质上并非是不可变语言,我们无法通过编译器查错。
1491+
即使没有函数式支持,像 C 这样的基础语言,也可以按照一定的原则编写纯函数式程序。Java 8 让函数式编程更简单,不过我们要确保一切是 `final` 的,同时你的所有方法和函数没有副作用。因为 Java 在本质上并非是不可变语言,我们无法通过编译器查错。
14931492

14941493
这种情况下,我们可以借助第三方工具[^9],但使用 Scala 或 Clojure 这样的语言可能更简单。因为它们从一开始就是为保持不变性而设计的。你可以采用这些语言来编写你的 Java 项目的一部分。如果必须要用纯函数式编写,则可以用 Scala(需要一些规则) 或 Clojure (需要的规则更少)。虽然 Java 支持[并发编程](./24-Concurrent-Programming.md),但如果这是你项目的核心部分,你应该考虑在项目部分功能中使用 `Scala``Clojure` 之类的语言。
14951494

@@ -1509,7 +1508,7 @@ Lambda 表达式和方法引用并没有将 Java 转换成函数式语言,而
15091508

15101509
[^1]: 功能粘贴在一起的方法的确有点与众不同,但它仍不失为一个库。
15111510
[^2]: 例如,这个电子书是利用 [Pandoc](http://pandoc.org/) 制作出来的,它是用纯函数式语言 [Haskell](https://www.haskell.org/) 编写的一个程序 。
1512-
[^3]: 有时函数式语言将其描述为“代码即数据”。
1511+
[^3]: 有时函数式语言将其描述为“代码即数据”。
15131512
[^4]: 这个语法来自 C++。
15141513
[^5]: 我还没有验证过这种说法。
15151514
[^6]: 当你理解了[并发编程](./24-Concurrent-Programming.md)章节的内容,你就能明白为什么更改共享变量 “不是线程安全的” 的了。

0 commit comments

Comments
 (0)