多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
## [for-in 语法](https://lingcoder.gitee.io/onjava8/#/book/05-Control-Flow?id=for-in-%e8%af%ad%e6%b3%95) Java 5 引入了更为简洁的“增强版**for**循环”语法来操纵数组和集合。(更多细节,可参考[数组](https://lingcoder.gitee.io/onjava8/#/./21-Arrays)和[集合](https://lingcoder.gitee.io/onjava8/#/./12-Collections)章节内容)。大部分文档也称其为**for-each**语法,但因为了不与 Java 8 新添的`forEach()`产生混淆,因此我称之为**for-in**循环。 (Python 已有类似的先例,如:**for x in sequence**)。**注意**:你可能会在其他地方看到不同叫法。 **for-in**无需你去创建**int**变量和步进来控制循环计数。 下面我们来遍历获取**float**数组中的元素。代码示例: ~~~ // control/ForInFloat.java import java.util.*; public class ForInFloat { public static void main(String[] args) { Random rand = new Random(47); float[] f = new float[10]; for(int i = 0; i < 10; i++) f[i] = rand.nextFloat(); for(float x : f) System.out.println(x); } } ~~~ 输出结果: ~~~ 0.72711575 0.39982635 0.5309454 0.0534122 0.16020656 0.57799757 0.18847865 0.4170137 0.51660204 0.73734957 ~~~ 上例中我们展示了传统**for**循环的用法。接下来再来看下**for-in**的用法。代码示例: ~~~ for(float x : f) { ~~~ 这条语句定义了一个**float**类型的变量`x`,继而将每一个`f`的元素赋值给它。 任何一个返回数组的方法都可以使用**for-in**循环语法来遍历元素。例如**String**类有一个方法`toCharArray()`,返回值类型为**char**数组,我们可以很容易地在**for-in**循环中遍历它。代码示例: ~~~ // control/ForInString.java public class ForInString { public static void main(String[] args) { for(char c: "An African Swallow".toCharArray()) System.out.print(c + " "); } } ~~~ 输出结果: ~~~ A n A f r i c a n S w a l l o w ~~~ 很快我们能在[集合](https://lingcoder.gitee.io/onjava8/#/./12-Collections)章节里学习到,**for-in**循环适用于任何可迭代(*iterable*)的 对象。 通常,**for**循环语句都会在一个整型数值序列中步进。代码示例: ~~~ for(int i = 0; i < 100; i++) ~~~ 正因如此,除非先创建一个**int**数组,否则我们无法使用**for-in**循环来操作。为简化测试过程,我已在`onjava`包中封装了**Range**类,利用其`range()`方法可自动生成恰当的数组。 在[封装](https://lingcoder.gitee.io/onjava8/#/./07-Implementation-Hiding)(Implementation Hiding)这一章里我们介绍了静态导入(static import),无需了解细节就可以直接使用。 有关静态导入的语法,可以在**import**语句中看到: ~~~ // control/ForInInt.java import static onjava.Range.*; public class ForInInt { public static void main(String[] args) { for(int i : range(10)) // 0..9 System.out.print(i + " "); System.out.println(); for(int i : range(5, 10)) // 5..9 System.out.print(i + " "); System.out.println(); for(int i : range(5, 20, 3)) // 5..20 step 3 System.out.print(i + " "); System.out.println(); for(int i : range(20, 5, -3)) // Count down System.out.print(i + " "); System.out.println(); } } ~~~ 输出结果: ~~~ 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()`方法已被[重载](https://lingcoder.gitee.io/onjava8/#/./06-Housekeeping?id=%e6%96%b9%e6%b3%95%e9%87%8d%e8%bd%bd)(重载:同名方法,参数列表或类型不同)。上例中`range()`方法有多种重载形式:第一种产生从 0 至范围上限(不包含)的值;第二种产生参数一至参数二(不包含)范围内的整数值;第三种形式有一个步进值,因此它每次的增量为该值;第四种`range()`表明还可以递减。`range()`无参方法是该生成器最简单的版本。有关内容会在本书稍后介绍。 `range()`的使用提高了代码可读性,让**for-in**循环在本书中适应更多的代码示例场景。 请注意,`System.out.print()`不会输出换行符,所以我们可以分段输出同一行。 *for-in*语法可以节省我们编写代码的时间。 更重要的是,它提高了代码可读性以及更好地描述代码意图(获取数组的每个元素)而不是详细说明这操作细节(创建索引,并用它来选择数组元素) 本书推荐使用*for-in*语法。