更新第十三章目录子标题

This commit is contained in:
LingCoder
2019-03-24 23:45:09 +08:00
parent f15da1385c
commit 01d74ec40b
2 changed files with 30 additions and 19 deletions

View File

@@ -161,15 +161,15 @@
* [for-in和迭代器](book/12-Collections.md#for-in和迭代器)
* [本章小结](book/12-Collections.md#本章小结)
* [第十三章 函数式编程](book/13-Functional-Programming.md)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [](book/13-Functional-Programming.md#)
* [旧vs新](book/13-Functional-Programming.md#旧vs新)
* [Lambda表达式](book/13-Functional-Programming.md#Lambda表达式)
* [方法引用](book/13-Functional-Programming.md#方法引用)
* [函数式接口](book/13-Functional-Programming.md#函数式接口)
* [高阶函数](book/13-Functional-Programming.md#高阶函数)
* [闭包](book/13-Functional-Programming.md#闭包)
* [函数组合](book/13-Functional-Programming.md#函数组合)
* [Currying和Partial-Evaluation](book/13-Functional-Programming.md#Currying和Partial-Evaluation)
* [纯函数式编程](book/13-Functional-Programming.md#纯函数式编程)
* [本章小结](book/13-Functional-Programming.md#本章小结)
* [第十四章 流式编程](book/14-Streams.md)
* [](book/14-Streams.md#)

View File

@@ -1,6 +1,7 @@
[TOC]
# 第十三章-函数式编程
<!-- Functional Programming -->
# 第十三章 函数式编程
@@ -28,9 +29,10 @@ OO (object oriented) 是抽象数据FP (functional programming) 是抽象行
FP的想法值得融入非FP语言。 例如这种情况发生在Python语言中。 Java 8在FP中添加了自己的功能我们将在此章探讨。
<!-- Old vs. New -->
## 旧 VS 新
<!-- Old vs. New -->
## 旧vs新
通常,方法会根据我们传递的数据产生不同的结果。 如果您希望某个方法在从一个调用到下一个调用时表现不同,该怎么办? 如果我们将代码传递给方法,我们可以控制它的行为。 以前,我们通过在方法中创建包含所需行为的对象,然后将该对象传递给我们想要控制的方法来完成此操作。 以下示例显示了这一点,然后添加了 Java 8方法方法引用和 lambda 表达式。
@@ -110,7 +112,10 @@ Hello there Hello there
在Java 8之前我们已经能够通过[1]和[2]传递功能。但是,写入和读取的语法非常笨拙,我们只在强制时才这样做。 方法引用和lambda表达式可以在您需要时传递功能而不是仅在必要时传递功能。
## Lambda 表达式
<!-- Lambda Expressions -->
## Lambda表达式
Lambda表达式是使用最小可能语法编写的函数定义
@@ -273,9 +278,9 @@ public class RecursiveFibonacci {
将Fibonacci 序列对中的最后两个元素求和来产生下一个元素。
<!-- method references-->
## 方法引用
Java 8 方法引用指的是没有以前版本的 Java 所需的额外包袱的方法。 方法引用是类名或对象名,后面跟 :: [^4],然后是方法的名称。
```java
@@ -523,8 +528,10 @@ public class CtorReference {
编译器可以看到调用函数方法( 在本例中为make意味着调用构造函数。
<!-- Functional Interfaces -->
## 函数式接口
方法引用和lambda表达式都是必须赋值的并且这些赋值需要编译器的类型信息以确保类型正确性。 Lambda表达式特别引入了新的要求。 考虑:
```java
@@ -889,9 +896,9 @@ public interface IntToDoubleFunction {
当然,如果由于缺少原始类型的函数而导致性能实际上成为问题,您可以轻松编写自己的接口( 使用Java库源进行参考 - 尽管这似乎不太可能是您的性能瓶颈。
<!-- Higher-Order Functions-->
## 高阶函数
这个名字听起来有点令人生畏,但是:高阶函数只是一个消耗或产生函数的函数。
我们先来看看产生一个函数:
@@ -984,8 +991,10 @@ O
在这里,**transform**生成一个与传入的函数具有相同签名的函数,但是您可以生成任何您想要的类型。这在 **Function** 接口中使用名为 **andThen**的默认方法,该方法专门用于操作函数。 顾名思义在调用in函数之后调用 **toThen**(还有 **compose**,它在 **in** 函数之前应用新函数)。 要附加一个**andThen**函数,我们只需将该函数作为参数传递。 **transform**产生的是一个新函数,它将 **in** 的动作与 **andThen**参数的动作结合起来。
<!-- Closures -->
## 闭包
在上一节的 **ProduceFunction.java** 中,我们从方法返回了一个 lambda 函数。 这个例子让事情变得简单,但是我们必须在返回 lambdas 时探讨一些问题。
*闭包*一词概括了这些问题。 闭包非常重要,因为它们可以轻松生成函数。
@@ -1236,9 +1245,9 @@ public class AnonymousClosure {
事实证明只要有内部类就会有闭包Java 8只 会使闭包变得更容易)。 在 Java 8 之前,要求是 **x****i** 被明确声明为 **final**。 使用 Java 8内部类的规则已经放宽包括 “effectively final”。
<!-- Function Composition -->
## 函数组合
函数组合基本上意味着“将函数粘贴在一起以创建新函数”,它通常被认为是函数编程的一部分。您在**TransformFunction.java** 中看到了一个使用 **andThen()** 的函数组合示例。一些 **java.util** 的函数接口包含支持函数组合的方法。
Compositional Supporting Method Interfaces Function BiFunction Consumer BiConsumer IntConsumer andThen(argument) Performs the original LongConsumer operation followed by DoubleConsumer the argument operation.
@@ -1309,8 +1318,8 @@ foobaz
你可以从输出中看到 **p4** 是如何工作的:任何带有 “foo ”的东西都会存活即使它的长度大于5。 “fongopuckey” 太长了,没有 “bar” 来保存它。
<!-- Currying and Partial Evaluation -->
## Currying和Partial-Evaluation
## Currying 和 Partial Evaluation
*Currying* 以 Haskell Curry 命名Haskell Curry 是其发明者之一,可能是唯一一个以他的名字命名的重要事物的计算机领域的人物(另一个是 Haskell 编程语言)。 Currying 意味着从一个函数开始,该函数接受多个参数,并将其转换为一系列函数,每个函数只接受一个参数。
@@ -1405,14 +1414,16 @@ public class CurriedIntAdd {
您可以在因特网上找到更多 currying 示例。 通常这些是 Java 以外的语言,但如果你理解它们的基本概念,它们应该很容易翻译。
<!-- Pure Functional Programming -->
## 纯函数式编程
在没有函数支持的情况下即使用像C这样的原始语言也可以按照一定的原则编写纯函数程序。Java使它比这更容易但是您必须小心地使一切都成为 **final**,并确保您的所有方法和函数没有副作用。因为 Java 本质上不是一种不可变的语言,所以如果您犯了错误,编译器不会提供任何帮助。
有第三方工具可以帮助您[^9],但是使用 **Scala****Clojure** 这样的语言可能更容易,因为它们从一开始就是为保持不变性而设计的。这些语言使您可以用 Java 编写项目的一部分,如果您必须用纯函数式编写,则可以用**Scala** 编写其他部分 (这需要一些规则) 或 **Clojure** (这需要的少得多)。虽然您将在并发编程一章中看到 Java确实支持并发但是如果这是您项目的核心部分您可能会考虑至少在项目的一部分中使用 **Scala** 或 **Clojure**之类的语言。
## 总结
<!-- Summary -->
## 本章小结
Lambda 表达式和方法引用并没有将 Java 转换成函数式语言,而是提供了对函数式编程的支持。它们对 Java 是一个巨大的改进,因为它们允许您编写更简洁、更干净、更容易理解的代码。在下一章中,您将看到它们如何启用流。如果你像我一样,你会喜欢流媒体。