1. 程式人生 > 實用技巧 >Java流程控制之Scanner類

Java流程控制之Scanner類

Scanner類

我們可以通過Scanner類來獲取使用者的輸入

基本語法:

Scanner scanner=new Scanner(System.in);

通過Scanner 類的next()或nextLine()方法獲取輸入的字串,在讀取前,要使用hasNext()或hasNextLine()判斷是否有輸入的資料

next()和nextLine()的比較

  • next():
    1. 一定要讀取到有效字元後才可以結束輸入
    2. 對輸入有效字元前遇到的空白,next()方法會自動去掉
    3. 只有輸入有效字元後才將其後面輸入的空白作為分隔符或者結束符
    4. next()不能得到帶有空格的字串

{補充說明一下,Markdown中怎麼調字型顏色

<font color=顏 色編碼> 文字內容 }

  • nextLine():
    1. 以Enter作為結束符,也就是說nextLine()方法返回的是輸入回車之前的所有字元
    2. 可以獲得空白

上程式碼

  • next()演示
package com.Gemin.scanner;

import java.util.Scanner;

public class Demo01 {
    public static void main(String[] args) {
        //建立一個掃描器物件,用於接收鍵盤資料
        Scanner scanner=new Scanner(System.in);
        System.out.println("使用next()方式接收:");
        //判斷使用者有沒有輸入字串
        if (scanner.hasNext()){
            String str=scanner.next();
            System.out.println("輸入的內容為 "+str);
        }
        //凡是屬於I/O流的類,如果用完不關閉就會一直佔用資源,要養成用完就關閉的良好習慣
        scanner.close();
    }
}

輸入為:Gemin is a hardworking boy !

輸出為
使用next()方式接收:
輸入的內容為 Gemin

  • nextLine()方法演示
package com.Gemin.scanner;

import java.util.Scanner;

public class Demo02 {
    public static void main(String[] args) {
        //建立一個掃描器物件,用於接收鍵盤資料
        Scanner scanner=new Scanner(System.in);
        System.out.println("使用nextLine()方式接收:");
        //判斷使用者有沒有輸入字串
        if (scanner.hasNextLine()){
            String str=scanner.nextLine();
            System.out.println("輸入的內容為 "+str);
        }
        //凡是屬於I/O流的類,如果用完不關閉就會一直佔用資源,要養成用完就關閉的良好習慣
        scanner.close();
    }
}

Scanner 的進階使用

hasNextInt、hasNextFloat、hasNextDouble

package com.Gemin.scanner;

import java.util.Scanner;

public class Demo03 {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        //從鍵盤接收資料
        int i =0;
        float f=0.0f;
        System.out.println("請輸入整數: ");
        if(in.hasNextInt()){
            i=in.nextInt();
            System.out.println("整數資料 "+i);
        }else {
            System.out.println("輸入的不是整數資料 !");
        }
        /*
        System.out.println("請輸入小數: ");
        if(in.hasNextFloat()){
            f=in.nextFloat();
            System.out.println("小數資料 "+f);
        }else {
            System.out.println("輸入的不是小數資料 !");
        }
        */
        in.close();
    }
}

hasNextDouble

package com.Gemin.scanner;

import java.util.Scanner;

public class Demo04 {
    public static void main(String[] args) {
        //我們可以輸入多個數字,並求其總和與平均值,沒輸入一個數字用回車確認,通過輸入非數字來結束輸入並輸出執行結果
        Scanner in =new Scanner(System.in);
        //和
        double sum=0;
        //計算輸入了多少個數字
        int m=0;
        //通過迴圈判斷是否還有輸入,並在裡面進行一次求和運算和統計
        while (in.hasNextDouble()){
            double x=in.nextDouble();
            m++;
            sum+=x;
            System.out.println("你輸入了第"+m+"個數字,當前sum="+sum);
        }
        System.out.println("sum="+sum);
    }
}

在學習的Scanner的過程中還遇到了一點小插曲,是關於hasNext()的判斷問題

我同學突發奇想想從鍵盤輸入一串數字(包含int和float型別),並實現判斷輸入的資料型別

於是,我寫了段程式碼如下:

package com.Gemin.scanner;

import java.util.Scanner;

public class DataType {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        while(in.hasNext()) {
            String input = in.next();
                try {
                    int i = Integer.parseInt(input);
                    System.out.println("int type: " + i);
                } catch (Exception e) {
                    float i = Float.parseFloat(input);
                    System.out.println("float type: " + i);
                }
            }
        in.close();
    }
}

這段程式碼能夠實現判斷輸入的數字的資料型別,但是問題來了,我的程式死迴圈了,停留在輸入等待區不能結束。why?how?

能夠使該程式陷入死迴圈的只有一個地方,對,沒錯就是while出問題。

那麼問題是什麼呢?

通過一番折騰,發現Scanner類的hasNext(),下面上原始碼:

//以下是java中Scanner類的hasNext()方法的原始碼
/**
     * Returns true if this scanner has another token in its input.
     * This method may block while waiting for input to scan.
     * The scanner does not advance past any input.
     *
     * @return true if and only if this scanner has another token
     * @throws IllegalStateException if this scanner is closed
     * @see java.util.Iterator
     */
    public boolean hasNext() {
        ensureOpen();
        saveState();
        modCount++;
        while (!sourceClosed) {
            if (hasTokenInBuffer()) {
                return revertState(true);
            }
            readInput();
        }
        boolean result = hasTokenInBuffer();
        return revertState(result);
    }

看不懂原始碼咋辦,看註釋啊!!

hasNext()只返回true當scanner中有另一個輸入時;

hasNext()有可能在等待輸入時發生阻塞;

說人話:

當執行到hasNext()時,它會先掃描緩衝區中是否有字元,有則返回true,繼續掃描。直到掃描為空,這時並不返回false,而是將方法阻塞,等待你輸入內容然後繼續掃描。(這段話是網上查的。。。)

所以,咋辦呢?

在輸入序列後面加一個結束字元來告訴系統,我輸入完成了,該結束了!

package com.Gemin.scanner;

import java.util.Scanner;

public class DataType {
    public static void main(String[] args) {
        Scanner in =new Scanner(System.in);
        //輸入序列以“#”號作為結束
        while(true) {
            String input = in.next();
            if(!input.equals("#")) {//字串內容判斷不能用“=”號
                try {
                    int i = Integer.parseInt(input);
                    System.out.println("int type: " + i);
                } catch (Exception e) {
                    float i = Float.parseFloat(input);
                    System.out.println("float type: " + i);
                }
            }else
                break;
            }
        in.close();
    }
}

這樣子程式就能在我們輸入“#”後成功結束了。