Java 的流程控制是什麼樣子的

圖片

本文大綱:圖片java

爲何須要流程控制

平時咱們作一件事,通常都會有個固定流程程序員

好比你想吃蘋果,你須要找到冰箱,打開冰箱門,取出蘋果,回到沙發上,而後開吃。編程

這個順序基本不能調換,你不能在打開冰箱門以前去取蘋果。按順序來控制,這是一種流程。數組

那若是你想吃香蕉,你會發現流程相似,只是從冰箱裏取出香蕉就行了。服務器

在這個過程裏,你會發現你最終吃什麼,取決於你的選擇。你要吃蘋果,你從冰箱裏取蘋果,你要吃香蕉,你從冰箱裏取香蕉。按選擇來控制,這也是一種流程。工具

那還有種狀況,一根香蕉不夠你吃,你還想吃幾根,直到你不想吃,那你就會重複上面的流程,當你吃飽的時候,就終止了。這種重複執行按照某個條件來終止的控制,也是一種流程。spa

計算機是現實世界的電子化表達,那麼在計算機的世界裏,程序運行也須要這樣的流程控制設計

不管是機器語言,仍是彙編語言,仍是高級程序設計語言,都會涉及這個概念,它決定了你寫的代碼會按照怎樣的路徑運行,也決定着計算機和用戶之間的交互方式code

咱們看看 Java 語言的流程控制是什麼樣的?對象

輸入和輸出

咱們編程都是爲了解決某個實際問題,好比寫一個加法程序,咱們是爲了得到兩個數的和是多少。

那你會發現,程序有個重要的特色,就是接收輸入,而後進行處理,最後輸出結果

圖片

那 Java 是怎麼接收輸入的呢?

Scanner 介紹

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 換成其餘基本類型一樣也適用。

Scanner 使用

咱們能夠看下樣例代碼:

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單選擇結構。

語法以下:

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雙選擇結構。

語法以下:

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多選擇結構。

語法以下:

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多選擇結構的變種。

語法以下:

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選擇結構。

語法以下:

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 2case 3default 都不會走到。

固然不是每一個 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(布爾表達式){
 //循環內容
}
  • 只要布爾表達式爲 true,循環就會一直執行下去。
  • 咱們大多數狀況是會讓循環中止下來的,所以須要一個讓布爾表達式爲 false 的方式來中止循環。
  • 少部分狀況時須要循環一直執行,好比服務器的請求響應監聽等。
  • 循環條件若是一直是 true,就會形成無限循環,應儘可能避免這種狀況,不然會形成程序卡死崩潰。

用 while 來表達求和代碼以下:

// 初始化值
a = 1;
sum = 0;

while (a <= 5) {
    // a 累加到 sum 中
    sum += a;
    // a 自身加一
    a++;
}
System.out.println("while sum:" + sum);

do while循環結構

觀察 while 語句,你會發現,只要不知足條件,就不能進入循環。但有時候咱們須要即便不知足條件,也至少要執行一次。那此時用 do while 循環就比較合適,語法以下:

do{
 //循環內容
}where(布爾表達式)
  • 不一樣於 while 循環結構的先判斷後執行的方式,do while 循環結構是先執行後判斷
  • do while 中的循環內容會被至少執行一次

用 do while 來表達求和代碼以下:

// 初始化值
a = 1;
sum = 0;

do {
    // a 累加到 sum 中
    sum += a;
    // a 自身加一
    a++;
} while (a <= 5);
System.out.println("do while sum:" + sum);

for循環結構

在求和代碼中,咱們會發現,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 each 循環結構,它能夠很簡單的遍歷數組,語法以下:

for(元素類型 元素變量 : 數組或迭代器){
 //循環內容
}
  • for each 是對 for 特殊場景下的簡化,處理對象是數組或者迭代器對象
  • 和 for 循環結構相比,for each 循環結構再也不體現計數器的初始化和更新,所以也沒法指定遍歷順序,也不能獲取數組或迭代器索引

用 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;
    }
    //中斷後代碼
}
  • 中斷布爾表達式返回 true 時,命中 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);
  • 實際對 1 和 2 進行求和,由於 a 爲 3 的時候退出了循環。

注意:循環結構若是存在嵌套,break 只會退出當前層循環結構,不會退出外層循環結構。

另外一種是 continue,語法以下:

循環結構{
    //中斷前代碼
    if(中斷布爾表達式){
  continue;
    }
    //中斷後代碼
}
  • 中斷布爾表達式返回 true 時,命中 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 的世界裏,輸入和輸出的實現方式,接着講解了在處理的過程當中,經常使用的三種流程控制結構:順序結構、選擇結構和循環結構,並列出了演示代碼。讀者能夠仿照案例實踐一把,相信你會有更深入的印象。感謝你的閱讀和分享,歡迎留言互動和點贊!


我是蝸牛,大廠程序員,專一技術原創和我的成長,正在互聯網上摸爬滾打。歡迎關注我,和蝸牛一塊兒成長,咱們一塊兒牛~下期見!

相關文章
相關標籤/搜索