From a2f78c207299e54b8a85b947c0efc9674427940f Mon Sep 17 00:00:00 2001 From: LingCoder Date: Fri, 5 Apr 2019 17:12:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=A1=E8=AE=A2=E7=AC=AC=E4=BA=94=E7=AB=A0?= =?UTF-8?q?=20=E6=9C=AA=E5=AE=8C...?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/book/05-Control-Flow.md | 64 +++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/docs/book/05-Control-Flow.md b/docs/book/05-Control-Flow.md index 545af60..707b0a3 100644 --- a/docs/book/05-Control-Flow.md +++ b/docs/book/05-Control-Flow.md @@ -211,7 +211,7 @@ value: 106 character: j #### 逗号操作符 -逗号运算符(不是逗号分隔符,逗号作为分隔符用于分隔定义和方法参数)在 Java 中只有一个用法:在**for** 循环的控制表达式中。 在控制表达式的初始化和步进控制中,您可以使用逗号分隔多个语句,并按顺序计算这些语句。使用逗号运算符,您可以在 **for** 语句中定义多个变量,但它们必须属于同一类型: +在 Java 中逗号运算符(这里并非指我们平常用于分隔定义和方法参数的逗号分隔符)仅有一种用法:在 **for** 循环的初始化和步进控制中定义多个变量。我们可以使用逗号分隔多个语句,并按顺序计算这些语句。**注意**:哟啊求定义的变量类型相同。代码示例: ```java // control/CommaOperator.java @@ -223,23 +223,25 @@ public class CommaOperator { } } } -/* Output: +``` + +输出结果: + +``` i = 1 j = 11 i = 2 j = 4 i = 3 j = 6 i = 4 j = 8 -*/ ``` -**for** 语句中的 **int** 定义覆盖了 **i** 和 **j**,在初始化部分实际上可以拥有任意数量的具有相同类型的变量定义。在控制表达式中定义变量的能力仅限于 **for** 循环。 您不能将此方法与任何其他选择或迭代语句一起使用。 -可以看到,无论在初始化还是在步进部分,语句都是顺序执行的。 +上例中 **int** 类型声明包含了 `i` 和 `j`。实际上,在初始化部分我们可以定义任意数量的同类型变量。**注意**:在 Java 中,仅允许 **for** 循环在控制表达式中定义变量。 我们不能将此方法与其他的循环语句和选择语句中一起使用。同时,我们可以看到:无论在初始化还是在步进部分,语句都是顺序执行的。 ## for-in语法 -Java 5引入了更简洁的 **for** 语法,用于数组和集合(您将在“数组和集合”章节中了解更多有关这些内容的信息)。 这有时被称为 **增强版for循环**,并且您将看到的大部分文档称为 *for-each* 语法,但Java 8添加了大量使用的 **forEach()**。 这会混淆术语,因此我称之为*for-in* (例如,在Python中,你实际上是 **for x in sequence**,所以有合理的先例)。 请记住,您可能会在其他地方看到它的不同叫法。 +Java 5 引入了更为简洁的“增强版 **for** 循环”语法来操纵数组和集合。(更多细节,可参考 [数组](./21-Arrays.md) 和 [集合](./12-Collections.md) 章节内容)。,大部分文档也称其为 **for-each** 语法,但因为了不与 Java 8 新添的 **forEach()** 产生混淆,因此我称之为 **for-in** 循环。 (Python 已有类似的先例,如:**for x in sequence**)。**注意**:你可能会在其他地方看到不同叫法。 -**for-in** 会自动为您生成每个项,因此你不必创建 **int** 变量去对由访问项构成的序列进行计数。 例如,假设您有一个 **float** 数组,并且您想要选取该数组中的每个元素: +**for-in** 无需你去创建 **int** 变量和步进来控制循环计数。 下面我们来遍历获取 **float** 数组中的元素。代码示例: ```java // control/ForInFloat.java @@ -256,7 +258,11 @@ public class ForInFloat { System.out.println(x); } } -/* Output: +``` + +输出结果: + +``` 0.72711575 0.39982635 0.5309454 @@ -267,18 +273,17 @@ public class ForInFloat { 0.4170137 0.51660204 0.73734957 -*/ ``` -这个数组是用旧式的for循环组装的,因为在组装时必须按索引访问它。在下面这行中可以看到foreach方法: +上例中我们展示了传统 **for** 循环的用法。接下来再来看下 **for-in** 的用法。代码示例: ```java for(float x : f) { ``` -这条语句定义了一个 **float** 类型的变量 **x**,继而将每一个 **f** 的元素赋值给 **x**。 +这条语句定义了一个 **float** 类型的变量 `x`,继而将每一个 `f` 的元素赋值给它。 -任何返回一个数组的方法都可以使用 **for-in**。例如 **String** 类有一个方法 **toCharArray()**,它返回一个 **char** 数组,因此可以很容易地下像下面这样迭代在字符串里面的所有字符: +任何一个返回数组的方法都可以使用 **for-in** 循环语法来遍历元素。例如 **String** 类有一个方法 `toCharArray()`,返回值类型为 **char** 数组,我们可以很容易地在 **for-in** 循环中遍历它。代码示例: ```java // control/ForInString.java @@ -289,22 +294,26 @@ public class ForInString { System.out.print(c + " "); } } -/* Output: -A n A f r i c a n S w a l l o w -*/ ``` -就像在集合的章节所看到的,for-in还可以用于任何 **iterable** 对象。 +输出结果: -许多 **for** 语句都会在一个整型值序列中步进,就像下面这样: +``` +A n A f r i c a n S w a l l o w +``` + +很快我们能在 [集合](./12-Collections.md) 章节里学习到, + **for-in** 循环适用于任何可迭代(*iterable*)的 对象。 + +通常, **for** 循环语句都会在一个整型数值序列中步进。代码示例: ```java for(int i = 0; i < 100; i++) ``` -对于这样的语句,for-in语法将不起作用,除非先创建一个 **int** 数组。为了简化这些任务,我会在**onjava.Range** 包中创建一个名为 **range()** 的方法,它将自动生成恰当的数组。 +正因如此,除非先创建一个 **int** 数组,否则我们无法使用 **for-in** 循环来操作。为简化测试过程,我已在 `onjava` 包中封装了 **Range** 类,利用其 `range()` 方法可自动生成恰当的数组。 -隐藏实施过程这一章节( Implementation Hiding )介绍了静态导入。 但是,您无需了解这些详细信息即可开始使用此库。 你可以在 **import** 语句中看到 **static import** 语法: +在 [封装](./07-Implementation-Hiding.md)(*Implementation Hiding*)这一章里我们介绍了静态导入(*static import*)。我们无需了解细节觉可以直接使用。 有关静态导入的语法,你可以在 **import** 语句中看到: ```java // control/ForInInt.java @@ -315,7 +324,7 @@ public class ForInInt { public static void main(String[] args) { for(int i : range(10)) // 0..9 System.out.print(i + " "); - System.out.println(); + System.out.println(); for(int i : range(5, 10)) // 5..9 System.out.print(i + " "); System.out.println(); @@ -327,21 +336,24 @@ public class ForInInt { System.out.println(); } } -/* Output: +``` + +输出结果: +``` 0 1 2 3 4 5 6 7 8 9 5 6 7 8 9 5 8 11 14 17 20 17 14 11 8 -*/ ``` -**range()** 方法已经被重载,重载表示相同的方法名可以具有不同的参数列表(你将很快学习重载)。**range()** 的第一个种重载形式是从0开始产生值,直到范围的上限,但不包括该上限。第二种重载形式是从第一个值开始产生值,直至比第二值小1的值为止。第三种形式有一个步进值,因此它每次的增量为该值。第四种 **range()** 表明还可以递减。**range()**是所谓生成器的一个非常简单的版本,有关生成器的内容将在本书稍后进行介绍。 -**range()** 允许在更多地方使用 for-in 语法,因此可以说提高可读性。 +`range()` 方法已被 [重载](./06-Housekeeping.md#方法重载)(重载:同名方法,参数列表或类型不同)。上例中 `range()` 方法有多种重载形式:第一种产生从 0 至范围上限(不包含)的值;第二种产生参数一至参数二(不包含)范围内的整数值;第三种形式有一个步进值,因此它每次的增量为该值;第四种 `range()` 表明还可以递减。`range()` 无参方法是该生成器最简单的版本。有关内容会在本书稍后介绍。 -请注意,**System.out.print()** 不会输出换行符,因此您可以分段输出一行。 +`range()` 的使用提高了代码可读性,让 **for-in** 循环在本书中适应更多的代码示例场景。 -*for-in* 语法不仅可以节省编写代码的时间。 更重要的是,它更容易阅读并说明你要做什么(获取数组的每个元素)而不是详细说明你是如何做到的(“我正在创建这个索引,所以我可以使用它来选择每个数组元素。“)。 本书只要有可能就会使用 *for-in* 语法。 +请注意,`System.out.print()` 不会输出换行符,所以我们可以分段输出同一行。 + +*for-in* 语法可以节省我们编写代码的时间。 更重要的是,它提高了代码可读性以及更好地描述代码意图(获取数组的每个元素)而不是详细说明这操作细节(创建索引,并用它来选择数组元素) 本书推荐使用 *for-in* 语法。 ## return