while語句
while 語句是一種基本語句脖阵,目的是讓 Java 執(zhí)行重復(fù)的操作良漱。換言之,while 語句是 Java的主要循環(huán)結(jié)構(gòu)之一鲸伴。句法如下:
while (expression)
????????statement
while 語句先計(jì)算 expression 的值澜沟,計(jì)算結(jié)果必須是布爾值灾票。如果計(jì)算結(jié)果為 false,解釋器跳過循環(huán)中的 statement茫虽,執(zhí)行程序中的下一個(gè)語句刊苍。如果計(jì)算結(jié)果為 true,解釋器執(zhí)行組成循環(huán)主體的 statement濒析,然后再次計(jì)算 expression 的值正什。如果計(jì)算結(jié)果為 false,解釋器執(zhí)行程序中的下一個(gè)語句;否則号杏,再次執(zhí)行 statement婴氮。只要 expression 的計(jì)算結(jié)果為 true,就會(huì)一直循環(huán)下去盾致,while 語句結(jié)束后(即 expression 的計(jì)算結(jié)果為 false)解釋器才會(huì)執(zhí)行下一個(gè)語句主经。
下面是一個(gè) while 循環(huán)示例,打印數(shù)字 0 到 9:
int count = 0;
while (count < 10) {
? ? ? ? System.out.println(count);
????????count++;
}
可以看出庭惜,在這個(gè)示例中罩驻,變量 count 的起始值是 0,循環(huán)主體每執(zhí)行一次蜈块,count 的值就會(huì)增加 1鉴腻。循環(huán)執(zhí)行 10 次后,表達(dá)式的計(jì)算結(jié)果變成 false(即 count 的值不再小于 10)百揭,此時(shí) while 語句結(jié)束爽哎,Java 解釋器繼續(xù)執(zhí)行程序中的下一個(gè)語句。大多數(shù)循環(huán)都有一個(gè)計(jì)數(shù)器變量器一,例如這個(gè)例子中的 count课锌。循環(huán)計(jì)數(shù)器變量的名稱經(jīng)常使用 i、j 和 k,不過你應(yīng)該使用意義更明確的名字渺贤,以便代碼更易理解雏胃。
do-while語句
do-while 循環(huán)和 while 循環(huán)很像,不過循環(huán)表達(dá)式不在循環(huán)開頭志鞍,而在循環(huán)末尾測試瞭亮。也就是說,循環(huán)主體至少會(huì)執(zhí)行一次固棚。do-while 循環(huán)的句法如下:
do
????????statement
while (expression);
注意统翩,do-while 循環(huán)和更普通的 while 循環(huán)有幾個(gè)不同點(diǎn)。首先此洲,do-while 循環(huán)既需要使用關(guān)鍵字 do標(biāo)記循環(huán)的開頭厂汗,也要使用關(guān)鍵字 while 標(biāo)記循環(huán)的結(jié)尾,以及引入循環(huán)條件呜师。其次娶桦,與while 循環(huán)不同的是,do-while 循環(huán)的結(jié)尾要使用分號汁汗。這是因?yàn)?do-while 循環(huán)以循環(huán)條件結(jié)尾衷畦,而不是標(biāo)記循環(huán)主體結(jié)束的花括號。下面的 do-while 循環(huán)和前面的 while 循環(huán)打印相同的結(jié)果:
int count = 0;??
do{
? ? ? ? System.out.println(count);
????????count++;
}while(count < 10);
do-while 循環(huán)比類似的 while 循環(huán)少見得多碰酝,因?yàn)樵趯?shí)際使用中很少遇到一定會(huì)至少先執(zhí)行一次循環(huán)的情況霎匈。
for語句
for 語句提供的循環(huán)結(jié)構(gòu)往往比 while 和 do 循環(huán)更便利。for 語句利用了一般循環(huán)的執(zhí)行模式送爸。大多數(shù)循環(huán)都有一個(gè)計(jì)數(shù)器铛嘱,或者某種形式的狀態(tài)變量,在循環(huán)開始前初始化袭厂,然后測試這個(gè)變量的值墨吓,決定是否執(zhí)行循環(huán)主體,再次計(jì)算表達(dá)式的值之前纹磺,在循環(huán)主體末尾遞增或者以某種方式更新這個(gè)變量的值帖烘。初始化、測試和更新橄杨,這三步是循環(huán)變量的重要操作秘症,for 語句把這三步作為循環(huán)句法的明確組成部分:
for ( initialize;? test;? update) {
????????statement
}
for 循環(huán)基本等同于下面的 while 循環(huán):
initialize;
while (test) {
????????statement;
????????update;
}
把 initialize、test 和 update 三個(gè)表達(dá)式放在 for 循環(huán)的開頭式矫,特別有助于理解循環(huán)的作用乡摹,還能避免一些錯(cuò)誤,例如忘記初始化或更新循環(huán)變量采转。解釋器會(huì)丟掉 initialize和 update 兩個(gè)表達(dá)式的返回值聪廉,所以它們必須有副作用瞬痘。initialize 一般是賦值表達(dá)式,update 一般是遞增板熊、遞減或其他賦值表達(dá)式框全。
下面的 for 循環(huán)與前面的 while 和 do-while 循環(huán)一樣,打印數(shù)字 0 到 9:
int count;
for(count = 0 ; count < 10 ; count++)
? ? ? ? System.out.println(count);
注意干签,這種句法把循環(huán)變量的重要信息都放在同一行津辩,更能看清循環(huán)的執(zhí)行方式。而且容劳,把更新循環(huán)變量的表達(dá)式放在 for 語句中丹泉,還簡化了循環(huán)主體,只剩一個(gè)語句鸭蛙,甚至不需要使用花括號組成語句塊。
for 循環(huán)還支持一種句法筋岛,可以讓循環(huán)更便于使用娶视。很多循環(huán)都只在循環(huán)內(nèi)部使用循環(huán)變量,因此 for 循環(huán)允許 initialize 是一個(gè)完整的變量聲明表達(dá)式睁宰,這樣循環(huán)變量的作用域是循環(huán)主體肪获,在循環(huán)外部不可見。例如:
for(int count = 0 ; count < 10 ; count++)
????????System.out.println(count);
而且柒傻,for 循環(huán)的句法不限制只能使用一個(gè)變量孝赫,initialize 和 update 表達(dá)式都能使用逗號分隔多個(gè)初始化和更新表達(dá)式。例如:
for(int i = 0, j = 10 ; i < 10 ; i++, j--)
????????sum += i * j;
在目前所舉的例子中红符,計(jì)數(shù)器都是數(shù)字青柄,但 for 循環(huán)并不限制計(jì)數(shù)器只能使用數(shù)字。例如预侯,可以使用 for 循環(huán)迭代鏈表中的元素:
for(Node n = listHead; n != null; n = n.nextNode())
????????process(n);
for 循環(huán)中的 initialize致开、test 和 update 表達(dá)式都是可選的,只有分隔這些表達(dá)式的分號是必須的萎馅。如果沒有 test 表達(dá)式双戳,其值假定為 true。因此糜芳,可以使用 for(;;) 編寫一個(gè)無限循環(huán)飒货。
遍歷語句
Java 的 for 循環(huán)能很好地處理基本類型,但處理對象集合時(shí)沒什么用峭竣,而且笨拙塘辅。不過,有種叫作“遍歷循環(huán)”(foreach loop)的句法可以處理需要循環(huán)的對象集合邪驮。
遍歷循環(huán)以關(guān)鍵字 for 開頭莫辨,后面跟著一對括號,括號里是變量聲明(不初始化)、冒號和表達(dá)式沮榜,括號后面是組成循環(huán)主體的語句(或語句塊):
for( declaration : expression )
????????statement
別被遍歷循環(huán)這個(gè)名字迷惑了盘榨,它并不使用關(guān)鍵字 foreach。冒號一般讀作“......中”蟆融,例如“studentNames 中的各個(gè)名字”草巡。
介紹 while、do-while 和 for 循環(huán)時(shí)型酥,都舉了一個(gè)例子山憨,打印 10 個(gè)數(shù)字。遍歷循環(huán)也能做到弥喉,但需要迭代一個(gè)集合郁竟。為了循環(huán) 10 次(打印 10 個(gè)數(shù)字),我們需要一個(gè)有 10 個(gè)元素的數(shù)組或其他集合由境。我們可以使用下面的代碼:
// 這些是我們想打印的數(shù)字
int[]? primes = new int[] { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29 };
// 這是打印這些數(shù)字的循環(huán)
for(int n : primes)
? ? ? ? ? System.out.println(n);
遍歷for( declaration : expression )不能做的事
遍歷和 while棚亩、for 或 do-while 循環(huán)不同,因?yàn)樗[藏了循環(huán)計(jì)數(shù)器或 Iterator 對象虏杰。介紹lambda 表達(dá)式時(shí)會(huì)看出來讥蟆,這種想法很好,但有些算法不能使用遍歷循環(huán)自然地表達(dá)出來纺阔。
假如你想把數(shù)組中的元素打印出來瘸彤,各元素使用逗號分隔。為此笛钝,要在數(shù)組的每個(gè)元素后面打印一個(gè)逗號质况,但最后一個(gè)元素后面沒有逗號;或者說,數(shù)組的每個(gè)元素前面都要打印一個(gè)逗號玻靡,但第一個(gè)元素前面沒有逗號拯杠。使用傳統(tǒng)的 for 循環(huán),代碼可以這樣寫:
for(int i = 0; i < words.length; i++) {
????????if (i > 0)?
????????????????System.out.print(", ");
????????System.out.print(words[i]);
}
這是很簡單的任務(wù)啃奴,但遍歷做不到潭陪,因?yàn)楸闅v循環(huán)沒有循環(huán)計(jì)數(shù)器,也沒有其他能識別第一次最蕾、最后一次或中間某次迭代的方式依溯。
使用遍歷循環(huán)迭代集合中的元素也有類似的問題。使用遍歷循環(huán)迭代數(shù)組時(shí)無法獲取當(dāng)前元素的索引瘟则,同樣黎炉,使用遍歷循環(huán)迭代集合也無法獲取列舉集合元素的 Iterator 對象。
還有一些事情遍歷循環(huán)做不到:
1? ?反向迭代數(shù)組或 List 對象中的元素;
2? ?使用同一個(gè)循環(huán)計(jì)數(shù)器獲取兩個(gè)不同數(shù)組同一索引位的元素;
3? ?調(diào)用 List 對象的 get() 方法無法迭代其中的元素醋拧,必須調(diào)用 List 對象的迭代器慷嗜。