本文大綱:java
平時咱們作一件事,通常都會有個固定流程。程序員
好比你想吃蘋果,你須要找到冰箱,打開冰箱門,取出蘋果,回到沙發上,而後開吃。編程
這個順序基本不能調換,你不能在打開冰箱門以前去取蘋果。按順序來控制,這是一種流程。數組
那若是你想吃香蕉,你會發現流程相似,只是從冰箱裏取出香蕉就行了。服務器
在這個過程裏,你會發現你最終吃什麼,取決於你的選擇。你要吃蘋果,你從冰箱裏取蘋果,你要吃香蕉,你從冰箱裏取香蕉。按選擇來控制,這也是一種流程。工具
那還有種狀況,一根香蕉不夠你吃,你還想吃幾根,直到你不想吃,那你就會重複上面的流程,當你吃飽的時候,就終止了。這種重複執行按照某個條件來終止的控制,也是一種流程。spa
計算機是現實世界的電子化表達,那麼在計算機的世界裏,程序運行也須要這樣的流程控制。設計
不管是機器語言,仍是彙編語言,仍是高級程序設計語言,都會涉及這個概念,它決定了你寫的代碼會按照怎樣的路徑運行,也決定着計算機和用戶之間的交互方式。code
咱們看看 Java 語言的流程控制是什麼樣的?對象
咱們編程都是爲了解決某個實際問題,好比寫一個加法程序,咱們是爲了得到兩個數的和是多少。
那你會發現,程序有個重要的特色,就是接收輸入,而後進行處理,最後輸出結果。
那 Java 是怎麼接收輸入的呢?
Java 提供了 Scanner
工具類,咱們能夠經過這個工具類來獲取用戶的輸入。基本的語法以下:
// 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); // 讀取輸入的一行並獲取字符串 String nextLineStr = scanner.nextLine(); // 讀取輸入的字符串,會忽略掉字符串兩邊的空格,由於空格起分隔符或結束符的做用 String nextStr = scanner.next(); // 讀取輸入的整數,非整數會拋異常(InputMismatchException) int nextInt = scanner.nextInt();
System.in
是標準的輸入流,使用它能夠接收鍵盤輸入或其餘指定數據源的數據。
Scanner
是一個簡單的文本掃描器,經過它能夠解析基本類型和字符串。new Scanner(System.in)
能夠構建出一個掃描器對象,scanner.nextLine()
能夠讀取輸入的一行並獲取字符串,scanner.next()
也能夠獲取字符串,不過不能支持兩邊有空格的字符串,scanner.nextInt()
能夠讀取輸入的整數,int 換成其餘基本類型一樣也適用。
咱們能夠看下樣例代碼:
package cn.java4u.flowcontrol; import java.util.Scanner; /** * 輸入演示 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class InputDemo { public static void main(String[] args) { // 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); // 讀取輸入的一行並獲取字符串 String nextLineStr = scanner.nextLine(); // 讀取輸入的字符串,會忽略掉字符串兩邊的空格,由於空格起分隔符或結束符的做用 String nextStr = scanner.next(); // 讀取輸入的整數,非整數會拋異常(InputMismatchException) int nextInt = scanner.nextInt(); System.out.println("---如下爲打印值---"); System.out.println("nextLineStr:" + nextLineStr); System.out.println("nextStr:" + nextStr); System.out.println("nextInt:" + nextInt); } }
你會發現,樣例代碼裏有一個 import java.util.Scanner;
,Scanner 是 Java 類庫裏的一個類,因此須要 import 語法引入一下,才能使用。
樣例代碼有三次控制檯輸入,咱們輸入如下數據看下輸出:
我是蝸牛 蝸牛666 8
第一行輸入的字符串後邊有空格,第二行輸入的字符串先後都有空格。輸出以下:
---如下爲打印值--- nextLineStr:我是蝸牛 nextStr:蝸牛666 nextInt:8
你會發現 nextLineStr 後邊的空格還在,nextStr 先後的空格都沒有了。
咱們再看一種輸入:
我是蝸牛 蝸牛666 7
當咱們輸入兩行後,再回車,程序就直接輸出結果了:
nextLineStr:我是蝸牛 nextStr:蝸牛666 nextInt:7
因而可知 nextLine()
和 next()
之間的不一樣,nextInt()
是 next()
基礎上的類型轉換,特色能夠認爲和 next()
一致。
起始符 | 分隔符 | 特色 | |
---|---|---|---|
nextLine() | 任何字符 | 回車(Enter) | 能夠得到帶空格的字符串 |
next() | 非空白字符 | 空格 | 不能得到帶空格的字符串 |
在以前的代碼中,咱們都是經過 System.out.println()
的方式,把內容輸出到控制檯的。
其中 System.out
是標準的輸出流,經過它不僅能夠作顯示輸出,也能夠寫入到指定的輸出目標,好比文件。
println
是 print line 的縮寫,表示輸出並換行。若是輸出不想換行,可使用 print()
。此外,Java 也支持用 printf()
進行格式化輸出,以方便閱讀。
如下是示例代碼:
package cn.java4u.flowcontrol; /** * 輸出演示 * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class OutputDemo { public static void main(String[] args) { // 輸出並換行 System.out.println("---開始演示---"); // 輸出不換行 System.out.print("打印不換行["); System.out.print("1 "); System.out.print("2 "); System.out.print("3"); System.out.print("]"); // 只換行 System.out.println(); // 格式化輸出 double d = 66600000.8888; // 不進行格式化的處理結果:6.66000008888E7 System.out.println("不進行格式化的處理結果:" + d); System.out.printf("默認格式化:%f", d); System.out.printf("; 無小數格式化:%.0f", d); System.out.printf("; 一位小數格式化:%.1f", d); System.out.printf("; 兩位小數格式化:%.2f", d); } }
輸出結果以下:
---開始演示--- 打印不換行[1 2 3] 不進行格式化的處理結果:6.66000008888E7 默認格式化:66600000.888800; 無小數格式化:66600001; 一位小數格式化:66600000.9; 兩位小數格式化:66600000.89
%f
就是 Java 爲浮點數提供的格式化功能的佔位符,系統默認會把浮點數格式化成 6 位小數輸出,固然你也能夠仿照樣例指定小數位輸出。
除了浮點數,Java 的格式化功能還提供了多種佔位符,能夠把各類數據類型格式化成指定的字符串,如下是經常使用的佔位符:
佔位符 | 說明 |
---|---|
%d | 格式化輸出整數 |
%x | 格式化輸出十六進制整數 |
%f | 格式化輸出浮點數 |
%e | 格式化輸出科學計數法表示的浮點數 |
%s | 格式化字符串 |
注意,因爲 % 表示佔位符,所以,連續兩個 %% 表示一個 % 字符自己。
知道了輸入和輸出在 Java 世界裏的表達方式,咱們再看下在程序處理中涉及到的流程控制有哪些。
程序基本的流程結構就是順序結構,Java 也是如此。若是沒有特別指明,程序都是按照順序一行一行執行。
但不少時候,咱們須要判斷一個東西是否可行,而後纔去執行一段邏輯。好比加法程序,咱們得要求參與運算的值是數字而不能是字符串。
那這樣的流程控制能夠經過選擇結構來實現。
若是隻是想針對某個條件特殊處理下,處理先後的邏輯不變,此時可使用if單選擇結構。
語法以下:
if(布爾表達式){ //布爾表達式結果爲 true 時執行的語句 }
如下是打印兩個整數的最大值的示例代碼:
package cn.java4u.flowcontrol; import java.util.Scanner; /** * if 單選擇結構 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class IfSingleChoiceDemo { public static void main(String[] args) { // 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); System.out.println("請輸入整數a:"); int a = scanner.nextInt(); System.out.println("請輸入整數b:"); int b = scanner.nextInt(); // 初始化最大值爲 a 的值 int max = a; // b 比 a 大的請求下,把 b 的值賦給 max if (a < b) { max = b; } System.out.println("max:" + max); } }
咱們用數字 a 初始化了變量 max,只有發現 b 比 a 大的時候,纔會把 b 的值賦給 max。也就是 當 a=10 而且 b=9 時,if 花括號裏的邏輯是走不到的,當 a=10 而且 b=11 時,if 花括號裏的邏輯會走到。
有時候咱們遇到某個條件,會有兩種不一樣的邏輯,此時可使用if雙選擇結構。
語法以下:
if(布爾表達式){ //布爾表達式結果爲 true 時執行的語句 }else{ //布爾表達式結果爲 false 時執行的語句 }
如下是打印整數絕對值的示例代碼:
package cn.java4u.flowcontrol; import java.util.Scanner; /** * if雙選擇結構 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class IfDoubleChoiceDemo { public static void main(String[] args) { // 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); System.out.println("請輸入整數a:"); //10,-10 切換 int a = scanner.nextInt(); // 初始化絕對值變量 int abs; if (a < 0) { abs = -a; } else { abs = a; } System.out.println("abs:" + abs); } }
咱們用 abs 初始化了絕對值變量,針對待斷定的整數 a,當它的值是 10 或者 -10 時,會走 if 的不一樣分支執行不同的邏輯。
當咱們遇到的條件不僅一個的時候,咱們執行邏輯的狀況可能會超過兩個,此時可使用if多選擇結構。
語法以下:
if(布爾表達式1){ //布爾表達式1結果爲 true 時執行的語句 }else if(布爾表達式2){ //布爾表達式2結果爲 true 時執行的語句 } else{ //布爾表達式結果爲 false 時執行的語句 }
如下是百分制成績評優良差的示例代碼:
package cn.java4u.flowcontrol; import java.util.Scanner; /** * if 多選擇結構 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class IfMultiChoiceDemo { public static void main(String[] args) { // 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); System.out.println("請輸入你的成績(百分制):"); //58,68,88,96,120 切換 int score = scanner.nextInt(); if (score > 0 && score < 60) { System.out.println("不合格"); } else if (score >= 60 && score < 80) { System.out.println("合格"); } else if (score >= 80 && score < 90) { System.out.println("良好"); } else if (score >= 90 && score <= 100) { System.out.println("優秀"); } else { System.out.println("非法輸入"); } } }
成績分數評優良差的程序存在區間多級判斷,比較適合if多選擇結構。
當咱們遇到的條件裏,又能拆出多個條件,有不一樣的執行邏輯時,可使用if嵌套選擇結構。if嵌套選擇結構能夠認爲是if多選擇結構的變種。
語法以下:
if(布爾表達式1){ //布爾表達式1結果爲 true 時執行的語句 if(布爾表達式2){ //布爾表達式2結果爲 true 時執行的語句 } }
如下是百分制成績評優良差變形後的示例代碼:
package cn.java4u.flowcontrol; import java.util.Scanner; /** * if嵌套選擇結構 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class IfNestChoiceDemo { public static void main(String[] args) { // 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); System.out.println("請輸入你的成績(百分制):"); //58,68,88,96,120 切換 int score = scanner.nextInt(); if (score >= 0 && score <= 100) { if (score < 60) { System.out.println("不合格"); } else if (score < 80) { System.out.println("合格"); } else if (score < 90) { System.out.println("良好"); } else { System.out.println("優秀"); } } else { System.out.println("非法輸入"); } } }
和普通的 if多選擇結構 的代碼不一樣在於,if嵌套選擇作了兩層選擇,第一層是輸入的合法性,第二層是對成績作分級。
咱們有時候遇到的條件比較有限,而且就是判斷一個變量與一系列中某個值是否相等,而後命中不一樣的值,會走向不一樣的邏輯。此時就可使用switch選擇結構。
語法以下:
switch(var){ case value1: // var 命中 value1 時執行的語句 break; case value2: // var 命中 value2 時執行的語句 break; //能夠有任意數量的case語句 // 默認的請求,上邊都沒命中,會走到該分支 default: //以上 case 都未命中或者未 break 會走到這裏 }
咱們若是把上邊提到的幾個程序打包給用戶使用,那就能夠經過 switch 來提供統一的入口,引導用戶鍵入1來路由到求最大值的程序裏,鍵入2路由到求絕對值的程序裏,鍵入3路由到成績分數評優良差的程序裏。示例代碼以下:
package cn.java4u.flowcontrol; import java.util.Scanner; /** * switch選擇結構 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class IfSwitchChoiceDemo { public static void main(String[] args) { // 用標準的輸入流構建一個 Scanner 對象 Scanner scanner = new Scanner(System.in); System.out.println("請選擇你要運行的程序(鍵入1表示求最大值,鍵入2表示求絕對值,鍵入3表示成績分數評優良差):"); int choice = scanner.nextInt(); switch (choice) { case 1: System.out.println("--開始求兩個數的最大值--"); IfSingleChoiceDemo.main(null); break; case 2: System.out.println("--開始求絕對值--"); IfDoubleChoiceDemo.main(null); break; case 3: System.out.println("--開始成績分數評優良差--"); IfMultiChoiceDemo.main(null); break; default: System.out.println("非法輸入"); } } }
跑一下這個程序,鍵入 1 你會發現開始執行求最大值的子程序裏,最大值打印後整個程序就結束了,這說明 break
起到了當前分支阻斷程序的做用。一旦命中 break
代碼,後邊的 case 2
、case 3
、default
都不會走到。
固然不是每一個 case 都須要有 break
的,當你有兩個 case 的邏輯一致,就能夠忽略 break
進行 case 合併,好比當鍵入 4 的時候,我要求和 3 效果一致,能夠改爲下面這樣:
case 3: case 4: System.out.println("--開始成績分數評優良差--"); IfMultiChoiceDemo.main(null); break;
沒有 break 的 case 邏輯會穿透到下一個 case,使用下一個 case 的代碼邏輯。
注意,switch選擇結構是if多選擇結構特殊場景下的變種,JavaSE 8 支持的變量類型有 byte、short、int、char、String、ENUM。
程序有時候會重複運行一段邏輯,若是按順序結構+選擇結構來組織代碼的話,這種狀況下須要寫不少重複的代碼才能實現。好比我要獲得從 1 到 5 的和:
1+2+3+4+5=?
個人代碼可能就是這樣:
package cn.java4u.flowcontrol; /** * while 循環結構演示 * * @author 蝸牛 * @from 公衆號:蝸牛互聯網 */ public class WhileCircleDemo { public static void main(String[] args) { int a = 1; int sum = 0; System.out.println("當前a的值爲:" + a); // a 累加到 sum 中 sum = sum + a; // a 自身加一 a = a + 1; System.out.println("當前a的值爲:" + a); sum = sum + a; a = a + 1; System.out.println("當前a的值爲:" + a); sum = sum + a; a = a + 1; System.out.println("當前a的值爲:" + a); sum = sum + a; a = a + 1; System.out.println("當前a的值爲:" + a); sum = sum + a; System.out.println("sum:" + sum); } }
你會發現重複邏輯不少,在 a = 5 的時候,累加才結束,結果才輸出。那若是有種機制能把這些重複的邏輯用簡潔的方式表達,那寫代碼就會方便不少。
這種機制就是循環結構。
最經常使用的循環結構是 while 循環,語法以下:
while(布爾表達式){ //循環內容 }
用 while 來表達求和代碼以下:
// 初始化值 a = 1; sum = 0; while (a <= 5) { // a 累加到 sum 中 sum += a; // a 自身加一 a++; } System.out.println("while sum:" + sum);
觀察 while 語句,你會發現,只要不知足條件,就不能進入循環。但有時候咱們須要即便不知足條件,也至少要執行一次。那此時用 do while 循環就比較合適,語法以下:
do{ //循環內容 }where(布爾表達式)
用 do while 來表達求和代碼以下:
// 初始化值 a = 1; sum = 0; do { // a 累加到 sum 中 sum += a; // a 自身加一 a++; } while (a <= 5); System.out.println("do while sum:" + sum);
在求和代碼中,咱們會發現,a 就像一個計數器,經過 a = 1
初始化一個值,而後在每次循環中加一來當成咱們求和時要加的那個數,a <= 5
做爲計數器循環檢測條件,決定了咱們的累加是加到 5 仍是 100,只要改爲 a <= 100
,累加到 100 就不會再執行循環。
這種實際上是迭代處理的通用結構:初始值、終止條件和計數器。因而 Java 提供了 for 循環結構,用來簡化這種場景下的 while 循環,語法以下:
for(計數器初始化; 布爾表達式; 循環後更新計數器){ //循環內容 }
用 for 來表達求和代碼以下:
sum = 0; for (a = 1; a <= 5; a++) { sum += a; } System.out.println("for sum:" + sum);
有些時候,咱們拿到一堆數處理,其實並不關心他們的次序,只要能遍歷到就能夠。好比數組裏的幾個值,我不關心值的索引,我只想知道這些值的總和是多少。此時就能夠用 for each 循環結構,它能夠很簡單的遍歷數組,語法以下:
for(元素類型 元素變量 : 數組或迭代器){ //循環內容 }
用 for each 來表達求和代碼以下:
int[] array = {1, 2, 3, 4, 5}; sum = 0; for (int temp : array) { sum += temp; } System.out.println("for each sum:" + sum);
循環結構都會有個布爾表達式做爲循環檢測條件,若是布爾表達式爲 false 時,就會終止循環,這是循環中斷的一種方式。
除此以外,Java 還提供了另外兩種循環結構中斷的方式。
一種是 break
。語法以下:
循環結構{ //中斷前代碼 if(中斷布爾表達式){ break; } //中斷後代碼 }
求和示例代碼以下:
int a = 1; int sum = 0; while (a <= 5) { // a 爲 3 的時候中斷 if (a == 3) { break; } // a 累加到 sum 中 sum += a; // a 自身加一 a++; } System.out.println("while sum:" + sum);
注意:循環結構若是存在嵌套,break 只會退出當前層循環結構,不會退出外層循環結構。
另外一種是 continue
,語法以下:
循環結構{ //中斷前代碼 if(中斷布爾表達式){ continue; } //中斷後代碼 }
示例代碼以下:
int i = 0; while (i <= 5) { i++; // i 爲 3 的時候中斷 if (i == 3) { System.out.println("命中 continue"); continue; } System.out.println("i=" + i); }
輸出:
i=1 i=2 命中 continue i=4 i=5 i=6
會發現 i 的值爲 3 的時候命中 continue 邏輯,當次循環不會繼續往下走,但會進入下一次循環。
簡單講,break
跳出當前層循環,循環結構停止,continue
跳出當次循環調用,當次調用停止。兩者都要配合 if
使用。
本文從現實案例引出了流程控制的概念,映射到編程領域,咱們把一個程序的執行,抽象成輸入-處理-輸出的過程。而後介紹了在 Java 的世界裏,輸入和輸出的實現方式,接着講解了在處理的過程當中,經常使用的三種流程控制結構:順序結構、選擇結構和循環結構,並列出了演示代碼。讀者能夠仿照案例實踐一把,相信你會有更深入的印象。感謝你的閱讀和分享,歡迎留言互動和點贊!
我是蝸牛,大廠程序員,專一技術原創和我的成長,正在互聯網上摸爬滾打。歡迎關注我,和蝸牛一塊兒成長,咱們一塊兒牛~下期見!