Java中BufferedReader与Scanner读入的区别详解

java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串。它本质上是使用正则表达式去读取不同的数据类型。

Java.io.BufferedReader类为了能够高效的读取字符序列,从字符输入流和字符缓冲区读取文本。

在Java中,我们都知道Java的标准输入串是System.in。但是我们却很少在Java中看到谁使用它,这是因为我们平时输入的都是一个字符串或者是一个数字等等。而System.in提供的read方法是通过字节来读取数据的,所以对我们来说不方便处理!

Scanner

在Java SE6提供了一个非常方便的输入数据的类Scanner,位于java.util包中,这个Scanner的具体用法为Scanner in = new Scanner(System.in)。

通过new创建一个Scanner对象,Scanner需要传入一个System.in作为参数,这个我们可以看作是Scanner通过其内部机制将System.in包装起来而实现数据的读取工作的。

Scanner对象通过一系列的in.nextXxx();方法来读取相应的基本类型的数据,通过in.hasNextXxx();方法来判断是否还有下一个数据。

然而,Scanner读取数据是按空格符(这其中包括空格键,Tab键,Enter键)来分割数据的。

只要遇到其中之一,Scanner的方法就会返回下一个输入(当然nextLine()方法的结束符为换行符,它会返回换行符之前的数据),这也就是我们会面临的另一个问题,当我们的输入数据中有空格时,我们就不会得到我们想要的数据,这样我们就要考虑到BufferReader来读取数据!

BufferReader

BufferReader位于java.io包中,使用BufferReader就相对来说没有那么多方法来让你选择!读取数据比较固定,这样格式也就相对来说比较单一,只要记住就这一读取数据的方法。

BufferedReader br = new BufferedReader (newInputStreamReader(System.in));

这个BufferReader对象通过readLine();方法来读取数据,readLine()是按Enter回车来读取一行数据的,只要在回车键之前的都会被readLine()方法返回。

readLine()方法返回的是字符串,因此要使用BufferReader输入一些字符之外的类型的数据,就要相对比较麻烦,需要通过一些XXXX.parseXxx();来转换相应的数据类型,(例如:int类型的用Integer.parseInt(需要转换的字符串))。

虽然麻烦一些,但通过BufferReader读入的效率要比Scanner高一倍,这个差距可想而知,而且读取的数据越多,效果就越明显。

需要注意的是使用BufferedReader对象的readLine()方法必须处理java.io.IOException异常。

两者的对比

1、Scanner提供了一系列nextXxx()方法,当我们确定输入的数据类型时,使用Scanner更加方便。也正是因为这个BufferedReader相对于Scanner来说要快一点,因为Scanner对输入数据进行类解析,而BufferedReader只是简单地读取字符序列。

2、Scanner和BufferedReader都设置了缓冲区,Scanner有很少的缓冲区(1KB字符缓冲)相对于BufferedReader(8KB字节缓冲),但是这是绰绰有余的。

3、BufferedReader是支持同步的,而Scanner不支持。如果我们处理多线程程序,BufferedReader应当使用。

4、Scanner输入的一个问题:在Scanner类中如果我们在任何7个nextXXX()方法之后调用nextLine()方法,这nextLine()方法不能够从控制台读取任何内容,并且,这游标不会进入控制台,它将跳过这一步。nextXXX()方法包括nextInt(),nextFloat(), nextByte(),nextShort(),nextDouble(),nextLong(),next()。

在BufferReader类中就没有那种问题。这种问题仅仅出现在Scanner类中,由于nextXXX()方法忽略换行符,但是nextLine()并不忽略它。如果我们在nextXXX()方法和nextLine()方法之间使用超过一个以上的nextLine()方法,这个问题将不会出现了;因为nextLine()把换行符消耗了。

程序示例

package com.zxt.base;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;

public classSystemInTest {
    private static Scanner sc;
    public static void main(String[] args) {
        // 使用Scanner输入
        sc = new Scanner(System.in);
        int num1 = sc.nextInt();
        int num2 = sc.nextInt();
        System.out.println("num1 + num2 = "+ (num1+ num2));

        // 使用BufferReader输入
        InputStreamReaderisr = newInputStreamReader(System.in);
        BufferedReaderbr = new BufferedReader(isr);
        try {
            int num3 = Integer.parseInt(br.readLine());
            int num4 = Integer.parseInt(br.readLine());
            System.out.println("num3 + num4 = "+ (num3+ num4));

        }catch(NumberFormatException | IOException e) {
            e.printStackTrace();
        }       

        // 使用Scanner输入会遇到的问题
        System.out.println();
        System.out.print("Enter an Integer:");
        int intValue = sc.nextInt();
        System.out.print("Enter a String:");
        StringstrValue = sc.nextLine();
        System.out.printf("You have entered intValue is " + intValue+ " and strValue is " + strValue);

        // 问题原因:由于nextXXX()方法忽略换行符,但是nextLine()并不忽略它。所以如果我们在nextXXX()方法后面使用nextLine()将会出现问题
        // 解决方案是:在使用nextXXX()方法后,在使用nextLine()读取下一行数据前,多使用一个nextLine()用来消耗换行符
        // int intValue = sc.nextInt();
        // sc.nextLine();
        // String strValue = sc.nextLine();

        // 或者使用BufferReader不会出现该问题
        System.out.println();
        try {
            System.out.print("Enter an Integer:");
            int intValue1 = Integer.parseInt(br.readLine());
            System.out.print("Enter a String:");
            StringstrValue1 = br.readLine();
            System.out.printf("You have entered intValue1 is " + intValue1+ " and strValue1 is " + strValue1);

        }catch(NumberFormatException | IOException e) {
            e.printStackTrace();
        }
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Java中Scanner类与BufferReader类的不同点(非常详细)

    java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串.它本质上是使用正则表达式去读取不同的数据类型. Java.io.BufferedReader类为了能够高效的读取字符序列,从字符输入流和字符缓冲区读取文本. 下面是两个类的不同之处: 当nextLine()被用在nextXXX()之后,用Scanner类有什么问题 尝试去猜测下面代码的输出内容: // Code using Scanner Class import java.util.Scanner; c

  • InputStreamReader和BufferedReader用法及实例讲解

    一.BufferedReader类 . 所属类库: java.lang.Object java.io.Reader java.io.BufferedReader . 基本概念 : public class BufferedReader    extends Reader 从字符输入流中读取文本,缓冲各个字符,从而实现字符.数组和行的高效读取. 可以指定缓冲区的大小,或者可使用默认的大小.大多数情况下,默认值足够大. 通常, Reader 所作的每个读取请求都会导致对底层字符或字节流进行相应的读取

  • Java输入流Scanner/BufferedReader使用方法示例

    1.使用Scanner 使用时需要引入包import java.util.Scanner;首先定义Scanner对象 Scanner sc = new Scanner(System.in);如果要输入整数,则 int n = sc.nextInt();String类型的,则String temp = sc.next(); 比如: 复制代码 代码如下: import java.util.Scanner; public class Test {    @SuppressWarnings("resou

  • Java 中的 BufferedReader 介绍_动力节点Java学院整理

    BufferedReader 介绍 BufferedReader 是缓冲字符输入流.它继承于Reader. BufferedReader 的作用是为其他字符输入流添加一些缓冲功能. BufferedReader 函数列表 BufferedReader(Reader in) BufferedReader(Reader in, int size) void close() void mark(int markLimit) boolean markSupported() int read() int

  • Java中BufferedReader与Scanner读入的区别详解

    java.util.Scanner类是一个简单的文本扫描类,它可以解析基本数据类型和字符串.它本质上是使用正则表达式去读取不同的数据类型. Java.io.BufferedReader类为了能够高效的读取字符序列,从字符输入流和字符缓冲区读取文本. 在Java中,我们都知道Java的标准输入串是System.in.但是我们却很少在Java中看到谁使用它,这是因为我们平时输入的都是一个字符串或者是一个数字等等.而System.in提供的read方法是通过字节来读取数据的,所以对我们来说不方便处理!

  • java中的i++和++i的区别详解

    java中的前加加++和后加加++,有很多人搞的很晕,不太明白!今天我举几个例子说明下前++和后++的区别! 其实大家只要记住一句话就可以了,前++是先自加再使用而后++是先使用再自加! 前++和后++总结:其实大家只要记住一句话就可以了,前++是先自加再使用而后++是先使用再自加! 请大家看下面的例子就明白了! public class Test { public static void main(String[] args) { //测试,前加加和后加加 //前++和后++总结:其实大家只要

  • Java中Validated、Valid 、Validator区别详解

    目录 1. 结论先出 JSR 380 Valid VS Validated 不同点? Validator 2. @Valid和​​​​​​​@Validated 注解 3. 例子 4.使用@Valid嵌套校验 5. 组合使用@Valid和@Validated 进行集合校验 6. 自定义校验 自定义约束注解 工作原理 结论 参考链接: 1. 结论先出 Valid VS Validated 相同点 都可以对方法和参数进行校验 @Valid和@Validated 两种注释都会导致应用标准Bean验证.

  • java中String StringBuffer和StringBuilder的区别详解

    目录 从声明定义上来谈 从结构上来谈 从线程安全来谈 总结 从声明定义上来谈 只有String 可以 直接声明创建 而 StringBuffer 与 StringBuilder 必须去new对象 这是因为只有String会在这种声明方式下去字符串常量池创建,其他则没有 StringBuffer stf = new StringBuffer("abc"); StringBuilder stb = new StringBuilder("abc"); StringBuff

  • Java中关于int和Integer的区别详解

    1.Java 中的数据类型分为基本数据类型和复杂数据类型 int是前者,integer 是后者(也就是一个类). 2.初始化时 复制代码 代码如下: int i = 1; Integer i = new Integer(1);   // (要把integer 当做一个类看) int 是基本数据类型(面向过程留下的痕迹,不过是对Java的有益补充) Integer 是一个类,是int的扩展,定义了很多的转换方法 类似的还有:float Float.double Double.string Stri

  • Java中JSONObject与JSONArray的使用区别详解

    最近公司开发的几个项目中,后台Action向前端传递数据都是Json格式,于是对JSONObject.JSONArray简单的研究了一下,废话不多说,想使用JSONObject.JSONArray,策则在项目中必须要有commons-lang.jar commons-beanutils.jar commons-collections.jar commons-logging.jar  ezmorph.jar json-lib-2.2.2-jdk15.jar 这些Jar包. 1.JSONObject

  • java中public class与class的区别详解

    在编写类的时候可以使用两种方式定义类:public class定义类:class定义类:如果一个类声明的时候使用了public class进行了声明,则类名称必须与文件名称完全一致.范例:定义一个类(文件名称为:Hello.java) 复制代码 代码如下: public class HelloDemo{    //声明一个类,类名称的命名规范:所有单词的首字母大写    public static void main(String args[]){    //主方法        System.

  • Java多线程通讯之wait,notify的区别详解

    下面通过代码给大家介绍java多线程通讯之wait notify的区别,具体内容如下所示: class Res{ public String username; public String sex; } class Out extends Thread{ Res res; public Out(Res res){ this.res=res; } @Override public void run() { //写操作 int count=0; while (true){ // synchroniz

  • 在C#和Java语言中for和foreach的区别详解

    for循环和foreach循环的区别 首先在这里声明一点,C#和Java这两种语言很相似,尤其是初学的数据类型那一部分,所以这里写的for和foreach的区别在C#和Java中都适用. 我会在下面分别列出两种语言的for和foreach分别循环打印一个数组,大家可以看看区别 话不多说,直接上代码: //c# //先创建一个数组 int[] arr = new int[3] {99, 11, 22}; //利用for循环打印(可以创建一个变量 i;判断这个i是否小于数组的长度;每次循环i自增1)

  • Java中的重要核心知识点之继承详解

    目录 一.继承 1.概念 2.语法 3.父类成员的访问 (1)子类中访问父类成员变量 (2)子类中访问父类成员方法 4.super关键字 5.子类构造方法 6.super和this 7.代码块执行顺序 8.父类成员在子类中的可见性 9.继承方式 10.final关键字 11.组合 一.继承 1.概念 继承(inheritance)机制:是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特 性的基础上进行扩展,增加新功能,这样产生新的类,称派生类.继承呈现了面向对象程序设计的

随机推荐