第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 对象的迭代器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容