第06部分:循环语句

while语句

while 语句是一种基本语句,目的是让 Java 执行重复的操作。换言之,while 语句是 Java的主要循环结构之一。句法如下:

while (expression)

        statement

while 语句先计算 expression 的值,计算结果必须是布尔值。如果计算结果为 false,解释器跳过循环中的 statement,执行程序中的下一个语句。如果计算结果为 true,解释器执行组成循环主体的 statement,然后再次计算 expression 的值。如果计算结果为 false,解释器执行程序中的下一个语句;否则,再次执行 statement。只要 expression 的计算结果为 true,就会一直循环下去,while 语句结束后(即 expression 的计算结果为 false)解释器才会执行下一个语句。


下面是一个 while 循环示例,打印数字 0 到 9:

int count = 0;

while (count < 10) {

        System.out.println(count);

        count++;

}

可以看出,在这个示例中,变量 count 的起始值是 0,循环主体每执行一次,count 的值就会增加 1。循环执行 10 次后,表达式的计算结果变成 false(即 count 的值不再小于 10),此时 while 语句结束,Java 解释器继续执行程序中的下一个语句。大多数循环都有一个计数器变量,例如这个例子中的 count。循环计数器变量的名称经常使用 i、j 和 k,不过你应该使用意义更明确的名字,以便代码更易理解。







do-while语句

do-while 循环和 while 循环很像,不过循环表达式不在循环开头,而在循环末尾测试。也就是说,循环主体至少会执行一次。do-while 循环的句法如下:

do

        statement

while (expression);

注意,do-while 循环和更普通的 while 循环有几个不同点。首先,do-while 循环既需要使用关键字 do标记循环的开头,也要使用关键字 while 标记循环的结尾,以及引入循环条件。其次,与while 循环不同的是,do-while 循环的结尾要使用分号。这是因为 do-while 循环以循环条件结尾,而不是标记循环主体结束的花括号。下面的 do-while 循环和前面的 while 循环打印相同的结果:

int count = 0;  

do{

        System.out.println(count);

        count++;

}while(count < 10);

do-while 循环比类似的 while 循环少见得多,因为在实际使用中很少遇到一定会至少先执行一次循环的情况。






for语句

for 语句提供的循环结构往往比 while 和 do 循环更便利。for 语句利用了一般循环的执行模式。大多数循环都有一个计数器,或者某种形式的状态变量,在循环开始前初始化,然后测试这个变量的值,决定是否执行循环主体,再次计算表达式的值之前,在循环主体末尾递增或者以某种方式更新这个变量的值。初始化、测试和更新,这三步是循环变量的重要操作,for 语句把这三步作为循环句法的明确组成部分:

for ( initialize;  test;  update) {

        statement

}

for 循环基本等同于下面的 while 循环:

initialize;

while (test) {

        statement;

        update;

}

把 initialize、test 和 update 三个表达式放在 for 循环的开头,特别有助于理解循环的作用,还能避免一些错误,例如忘记初始化或更新循环变量。解释器会丢掉 initialize和 update 两个表达式的返回值,所以它们必须有副作用。initialize 一般是赋值表达式,update 一般是递增、递减或其他赋值表达式。


下面的 for 循环与前面的 while 和 do-while 循环一样,打印数字 0 到 9:

int count;

for(count = 0 ; count < 10 ; count++)

        System.out.println(count);

注意,这种句法把循环变量的重要信息都放在同一行,更能看清循环的执行方式。而且,把更新循环变量的表达式放在 for 语句中,还简化了循环主体,只剩一个语句,甚至不需要使用花括号组成语句块。


for 循环还支持一种句法,可以让循环更便于使用。很多循环都只在循环内部使用循环变量,因此 for 循环允许 initialize 是一个完整的变量声明表达式,这样循环变量的作用域是循环主体,在循环外部不可见。例如:

for(int count = 0 ; count < 10 ; count++)

        System.out.println(count);

而且,for 循环的句法不限制只能使用一个变量,initialize 和 update 表达式都能使用逗号分隔多个初始化和更新表达式。例如:

for(int i = 0, j = 10 ; i < 10 ; i++, j--)

        sum += i * j;



在目前所举的例子中,计数器都是数字,但 for 循环并不限制计数器只能使用数字。例如,可以使用 for 循环迭代链表中的元素:

for(Node n = listHead; n != null; n = n.nextNode())

        process(n);


for 循环中的 initialize、test 和 update 表达式都是可选的,只有分隔这些表达式的分号是必须的。如果没有 test 表达式,其值假定为 true。因此,可以使用 for(;;) 编写一个无限循环。






遍历语句

Java 的 for 循环能很好地处理基本类型,但处理对象集合时没什么用,而且笨拙。不过,有种叫作“遍历循环”(foreach loop)的句法可以处理需要循环的对象集合。


遍历循环以关键字 for 开头,后面跟着一对括号,括号里是变量声明(不初始化)、冒号和表达式,括号后面是组成循环主体的语句(或语句块):

for( declaration : expression )

        statement

别被遍历循环这个名字迷惑了,它并不使用关键字 foreach。冒号一般读作“......中”,例如“studentNames 中的各个名字”。


介绍 while、do-while 和 for 循环时,都举了一个例子,打印 10 个数字。遍历循环也能做到,但需要迭代一个集合。为了循环 10 次(打印 10 个数字),我们需要一个有 10 个元素的数组或其他集合。我们可以使用下面的代码:

// 这些是我们想打印的数字

int[]  primes = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };

// 这是打印这些数字的循环

for(int n : primes)

          System.out.println(n);








遍历for( declaration : expression )不能做的事

遍历和 while、for 或 do-while 循环不同,因为它隐藏了循环计数器或 Iterator 对象。介绍lambda 表达式时会看出来,这种想法很好,但有些算法不能使用遍历循环自然地表达出来。


假如你想把数组中的元素打印出来,各元素使用逗号分隔。为此,要在数组的每个元素后面打印一个逗号,但最后一个元素后面没有逗号;或者说,数组的每个元素前面都要打印一个逗号,但第一个元素前面没有逗号。使用传统的 for 循环,代码可以这样写:

for(int i = 0; i < words.length; i++) {

        if (i > 0) 

                System.out.print(", ");

        System.out.print(words[i]);

}

这是很简单的任务,但遍历做不到,因为遍历循环没有循环计数器,也没有其他能识别第一次、最后一次或中间某次迭代的方式。


使用遍历循环迭代集合中的元素也有类似的问题。使用遍历循环迭代数组时无法获取当前元素的索引,同样,使用遍历循环迭代集合也无法获取列举集合元素的 Iterator 对象。


还有一些事情遍历循环做不到:

1   反向迭代数组或 List 对象中的元素;

2   使用同一个循环计数器获取两个不同数组同一索引位的元素;

3   调用 List 对象的 get() 方法无法迭代其中的元素,必须调用 List 对象的迭代器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容