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();
    }
}

这样子程序就能在我们输入“#”后成功结束了。

posted @ 2020-09-19 16:10  Gemin_Chang  阅读(204)  评论(0)    收藏  举报