- 好好學(xué)Java:從零基礎(chǔ)到項(xiàng)目實(shí)戰(zhàn)
- 歐陽(yáng)燊
- 2357字
- 2022-07-27 19:14:58
3.3.3 冒號(hào)的幾種用法
Java中的標(biāo)點(diǎn)符號(hào)主要有兩類用途:一類是運(yùn)算符,包括加號(hào)“+”、減號(hào)“-”、乘號(hào)“*”、除號(hào)“/”、取余號(hào)“%”、等號(hào)“=”、大于號(hào)“>”、小于號(hào)“<”、與號(hào)“&”、或號(hào)“|”、非號(hào)“!”、異或號(hào)“^”等;另一類是分隔符,包括區(qū)分代碼塊的花括號(hào)“{}”,容納特定語(yǔ)句的圓括號(hào)“()”,標(biāo)明數(shù)組元素的方括號(hào)“[]”,分隔長(zhǎng)句的分號(hào)“;”,分隔短句的逗號(hào)“,”,分隔包名、類名、方法名的點(diǎn)號(hào)“.”,等等。當(dāng)然還有幾個(gè)特殊的分隔符,比如三元運(yùn)算符“?:”,它的完整形式為“式子A ?式子B :式子C”。當(dāng)式子A成立時(shí),得到式子B的結(jié)果;當(dāng)式子A不成立時(shí),得到式子C的結(jié)果。在這些標(biāo)點(diǎn)符號(hào)中,尤以冒號(hào)最為特殊,之所以這么說(shuō),是因?yàn)镴ava編程一遇到特殊的分隔場(chǎng)景,基本都拿冒號(hào)做標(biāo)記。
冒號(hào)除了用在三元運(yùn)算符“?:”中外,至少還有其他3種用法,分別介紹如下。
1.switch-case的分支標(biāo)記
冒號(hào)的第二種用法出現(xiàn)在多路分支中。猶記得當(dāng)年switch-case并肩作戰(zhàn),switch給出了待判斷的變量名,每個(gè)case帶著數(shù)值再拖上具體的處理語(yǔ)句,case條件與處理語(yǔ)句之間以冒號(hào)分隔,其他情況由default處理,也通過(guò)冒號(hào)同處理語(yǔ)句區(qū)分開(kāi)。譬如下面的多路分支代碼,就能看到冒號(hào)的分隔作用:
// switch允許判斷某個(gè)變量的多個(gè)取值,并分別進(jìn)行單獨(dú)處理 switch (seq) { case 1: // seq值為1時(shí)進(jìn)入該分支 System.out.println("涼風(fēng)有信的謎底是“諷”"); break; // 跳出多路分支,即跳到switch分支的右花括號(hào)之后 case 2: // seq值為2時(shí)進(jìn)入該分支 System.out.println("秋月無(wú)邊的謎底是“二”"); break; // 跳出多路分支,即跳到switch分支的右花括號(hào)之后 default: // seq值為其他時(shí)進(jìn)入該分支 System.out.println("您的按鍵有誤"); break; // 跳出多路分支,即跳到switch分支的右花括號(hào)之后 }
2.for循環(huán)的數(shù)組元素遍歷
冒號(hào)的第三種用法跟數(shù)組的循環(huán)遍歷有關(guān)。要想把某個(gè)數(shù)組里的所有元素?cái)?shù)值都打印出來(lái),就得通過(guò)for循環(huán)依次取出數(shù)組的每個(gè)元素,再打印該元素的數(shù)值。以整型數(shù)組為例,利用for語(yǔ)句遍歷并打印元素的代碼如下:
int[] numbers={2, 3, 5, 7}; for (int i=0; i < numbers.length; i++) { int number=numbers[i]; // 獲取下標(biāo)為i的元素,并賦值給名為number的變量 System.out.println("number=" + number); }
上面的循環(huán)語(yǔ)句很常規(guī),用法形式也很常見(jiàn),無(wú)非是依次取出數(shù)組里的每個(gè)元素罷了。倘若此時(shí)不修改元素?cái)?shù)值,僅僅是讀取數(shù)值的話,那么可以簡(jiǎn)化成一套通用的循環(huán)模板,就像以下循環(huán)語(yǔ)句一樣(完整代碼見(jiàn)本章源碼的src\com\control\array\ColonErgodic.java):
int[] numbers={2, 3, 5, 7}; // 在for循環(huán)中,可利用“變量類型 變量名稱 : 數(shù)組名稱”的形式,直接把數(shù)組元素賦值給該變量 for (int number : numbers) { System.out.println("number="+number); }
上述的Java代碼把原循環(huán)內(nèi)部的變量number提前放到for后面的圓括號(hào)中,并且number與數(shù)組numbers之間用冒號(hào)分開(kāi),表示每次循環(huán)處理之前都把數(shù)組元素逐個(gè)賦值給number變量,然后循環(huán)內(nèi)部即可直接處理該變量。如此這般便優(yōu)化了先前的for循環(huán)代碼,免去了冗余的數(shù)組下標(biāo)、判斷條件以及自增操作。
3.多層循環(huán)的跳轉(zhuǎn)標(biāo)記
冒號(hào)的第四種用法也與循環(huán)語(yǔ)句有關(guān),但不限于for循環(huán),而是與for和while都有關(guān)聯(lián)。前述的循環(huán)處理基本上都只有一層循環(huán),然而實(shí)際開(kāi)發(fā)中常常會(huì)遇到多層循環(huán),也就是一個(gè)循環(huán)內(nèi)部嵌套了另一個(gè)循環(huán),看起來(lái)像是層巒疊嶂、反復(fù)重疊,故又被稱作多重循環(huán)。例如有一個(gè)二維數(shù)組,要想把它里面的所有元素都打印出來(lái),這便需要兩層循環(huán)才能搞定,第一層循環(huán)負(fù)責(zé)遍歷第一個(gè)維度的下標(biāo),而第二層循環(huán)負(fù)責(zé)遍歷第二個(gè)維度的下標(biāo),編碼上則需一個(gè)for循環(huán)嵌套另一個(gè)for循環(huán),具體的Java實(shí)現(xiàn)代碼如下(完整代碼見(jiàn)本章源碼的src\com\control\array\ColonJump.java):
double[][] triangle={ {-2.0, 0.0}, {0.0, -1.0}, {2.0, 1.0} }; // 下面通過(guò)多重循環(huán)依次打印二維數(shù)組里面的所有元素 for (int i=0; i<triangle.length; i++) { for (int j=0; j<triangle[i].length; j++) { System.out.println("value="+triangle[i][j]); } }
可見(jiàn)以上的多重循環(huán)代碼還是挺簡(jiǎn)單的,并未涉及復(fù)雜的break和continue操作。即使用到break和continue,處理邏輯也沒(méi)有什么特別之處,因?yàn)閎reak語(yǔ)句只能跳出當(dāng)前層次的循環(huán),不能跳出上個(gè)層次的循環(huán),continue語(yǔ)句同理。所以要想從內(nèi)層循環(huán)跳出外層循環(huán),就得設(shè)置一個(gè)標(biāo)記,從內(nèi)層循環(huán)跳到外層循環(huán)時(shí),通過(guò)判斷該標(biāo)記再?zèng)Q定是否立刻跳出外層循環(huán)。仍以前面的二維數(shù)組為例,假設(shè)在內(nèi)層循環(huán)找到某個(gè)元素為0.0,則立即結(jié)束全部循環(huán)(包括外層循環(huán)和內(nèi)層循環(huán)),按此思路編寫(xiě)的代碼例子如下:
// 處理要求:一旦發(fā)現(xiàn)數(shù)組元素等于0.0,就立即從第二層循環(huán)跳出第一層循環(huán)(跳出兩層循環(huán)) for (int i=0; i<triangle.length; i++) { boolean isFound=false; // 該布爾變量用來(lái)標(biāo)記是否找到0.0 for (int j=0; j<triangle[i].length; j++) { if (triangle[i][j] == 0.0) { isFound=true; // 找到了0.0 System.out.println("simple found 0.0"); break; // 跳出第二層循環(huán) } } if (isFound) { // 根據(jù)布爾變量判斷是否找到了0.0 break; // 跳出第一層循環(huán) } }
以上代碼固然實(shí)現(xiàn)了功能要求,但是兩個(gè)break的寫(xiě)法著實(shí)令人憋屈,而且布爾變量isFound純粹是到此一游。有沒(méi)有一種寫(xiě)法允許代碼直接從內(nèi)層循環(huán)跳出外層循環(huán)呢?與其讓布爾變量做標(biāo)記,不如給外層循環(huán)加一個(gè)記號(hào),然后內(nèi)層循環(huán)就能告訴編譯器,接下來(lái)的break語(yǔ)句要跳出指定標(biāo)記的循環(huán)。這時(shí)冒號(hào)便派上用場(chǎng)了,通過(guò)形如“標(biāo)記名稱: for或者while”的表達(dá)式,即可給指定循環(huán)起一個(gè)外號(hào),于是語(yǔ)句“break標(biāo)記名稱”便實(shí)現(xiàn)了跳出指定循環(huán)的需求。使用新寫(xiě)法改造前面的循環(huán)跳出代碼,修改之后的代碼如下:
// 下面的loop1是一個(gè)記號(hào),連同后面的冒號(hào)加在for前面,表示它指代這個(gè)for循環(huán) loop1 : for (int i=0; i<triangle.length; i++) { for (int j=0; j<triangle[i].length; j++) { if (triangle[i][j] == 0.0) { // 找到了0.0,準(zhǔn)備跳出外層循環(huán) System.out.println("loop1 found 0.0"); break loop1; // 跳出loop1代表的循環(huán),也就是跳出第一層循環(huán) } } }
以上代碼先在外層的for循環(huán)之前添加“l(fā)oop1 : ”,表明外層循環(huán)的綽號(hào)叫l(wèi)oop1,然后內(nèi)層循環(huán)的break語(yǔ)句改成“break loop1;”,表示跳出loop1這個(gè)外層循環(huán),這樣只需一個(gè)break語(yǔ)句就跳出多重循環(huán)了。除了break語(yǔ)句外,continue語(yǔ)句也允許帶上標(biāo)記名稱,比如“continue loop1”表示繼續(xù)loop1這個(gè)外層循環(huán)的下一次循環(huán)處理,并且while循環(huán)同樣認(rèn)可在break和continue后面添加標(biāo)記。當(dāng)然,利用前面介紹的冒號(hào)的第三種用法,上面的多重循環(huán)還能簡(jiǎn)化成以下代碼:
// 下面用到了兩種冒號(hào):一種用來(lái)標(biāo)記循環(huán);另一種用來(lái)簡(jiǎn)化數(shù)組遍歷 loop2 : for (double[] dot : triangle) { // dot等價(jià)于前面的triangle[i] for (double coordinate : dot) { // coordinate等價(jià)于前面的triangle[i][j] if (coordinate == 0.0) { // 找到了0.0,準(zhǔn)備跳出外層循環(huán) System.out.println("loop2 found 0.0"); break loop2; // 跳出loop2代表的循環(huán) } } }
如此一來(lái),上述的循環(huán)代碼聯(lián)合應(yīng)用了冒號(hào)的兩種用法,代碼也變得更加精練了。
- SQL Server 從入門到項(xiàng)目實(shí)踐(超值版)
- Practical Data Analysis Cookbook
- Android開(kāi)發(fā)精要
- 微服務(wù)設(shè)計(jì)原理與架構(gòu)
- MATLAB應(yīng)用與實(shí)驗(yàn)教程
- Learn Swift by Building Applications
- 游戲程序設(shè)計(jì)教程
- Python機(jī)器學(xué)習(xí)算法與實(shí)戰(zhàn)
- C語(yǔ)言程序設(shè)計(jì)同步訓(xùn)練與上機(jī)指導(dǎo)(第三版)
- Scala程序員面試算法寶典
- HTML5 APP開(kāi)發(fā)從入門到精通(微課精編版)
- Node.js 12實(shí)戰(zhàn)
- ASP.NET Core and Angular 2
- 城市信息模型平臺(tái)頂層設(shè)計(jì)與實(shí)踐
- MySQL數(shù)據(jù)庫(kù)應(yīng)用技術(shù)及實(shí)戰(zhàn)