Java中BufferedReader與Scanner讀入的區(qū)別詳解
java.util.Scanner類是一個(gè)簡(jiǎn)單的文本掃描類,它可以解析基本數(shù)據(jù)類型和字符串。它本質(zhì)上是使用正則表達(dá)式去讀取不同的數(shù)據(jù)類型。
Java.io.BufferedReader類為了能夠高效的讀取字符序列,從字符輸入流和字符緩沖區(qū)讀取文本。
在Java中,我們都知道Java的標(biāo)準(zhǔn)輸入串是System.in。但是我們卻很少在Java中看到誰(shuí)使用它,這是因?yàn)槲覀兤綍r(shí)輸入的都是一個(gè)字符串或者是一個(gè)數(shù)字等等。而System.in提供的read方法是通過(guò)字節(jié)來(lái)讀取數(shù)據(jù)的,所以對(duì)我們來(lái)說(shuō)不方便處理!
Scanner
在Java SE6提供了一個(gè)非常方便的輸入數(shù)據(jù)的類Scanner,位于java.util包中,這個(gè)Scanner的具體用法為Scanner in = new Scanner(System.in)。
通過(guò)new創(chuàng)建一個(gè)Scanner對(duì)象,Scanner需要傳入一個(gè)System.in作為參數(shù),這個(gè)我們可以看作是Scanner通過(guò)其內(nèi)部機(jī)制將System.in包裝起來(lái)而實(shí)現(xiàn)數(shù)據(jù)的讀取工作的。
Scanner對(duì)象通過(guò)一系列的in.nextXxx();方法來(lái)讀取相應(yīng)的基本類型的數(shù)據(jù),通過(guò)in.hasNextXxx();方法來(lái)判斷是否還有下一個(gè)數(shù)據(jù)。
然而,Scanner讀取數(shù)據(jù)是按空格符(這其中包括空格鍵,Tab鍵,Enter鍵)來(lái)分割數(shù)據(jù)的。
只要遇到其中之一,Scanner的方法就會(huì)返回下一個(gè)輸入(當(dāng)然nextLine()方法的結(jié)束符為換行符,它會(huì)返回?fù)Q行符之前的數(shù)據(jù)),這也就是我們會(huì)面臨的另一個(gè)問(wèn)題,當(dāng)我們的輸入數(shù)據(jù)中有空格時(shí),我們就不會(huì)得到我們想要的數(shù)據(jù),這樣我們就要考慮到BufferReader來(lái)讀取數(shù)據(jù)!
BufferReader
BufferReader位于java.io包中,使用BufferReader就相對(duì)來(lái)說(shuō)沒(méi)有那么多方法來(lái)讓你選擇!讀取數(shù)據(jù)比較固定,這樣格式也就相對(duì)來(lái)說(shuō)比較單一,只要記住就這一讀取數(shù)據(jù)的方法。
BufferedReader br = new BufferedReader (newInputStreamReader(System.in));
這個(gè)BufferReader對(duì)象通過(guò)readLine();方法來(lái)讀取數(shù)據(jù),readLine()是按Enter回車來(lái)讀取一行數(shù)據(jù)的,只要在回車鍵之前的都會(huì)被readLine()方法返回。
readLine()方法返回的是字符串,因此要使用BufferReader輸入一些字符之外的類型的數(shù)據(jù),就要相對(duì)比較麻煩,需要通過(guò)一些XXXX.parseXxx();來(lái)轉(zhuǎn)換相應(yīng)的數(shù)據(jù)類型,(例如:int類型的用Integer.parseInt(需要轉(zhuǎn)換的字符串))。
雖然麻煩一些,但通過(guò)BufferReader讀入的效率要比Scanner高一倍,這個(gè)差距可想而知,而且讀取的數(shù)據(jù)越多,效果就越明顯。
需要注意的是使用BufferedReader對(duì)象的readLine()方法必須處理java.io.IOException異常。
兩者的對(duì)比
1、Scanner提供了一系列nextXxx()方法,當(dāng)我們確定輸入的數(shù)據(jù)類型時(shí),使用Scanner更加方便。也正是因?yàn)檫@個(gè)BufferedReader相對(duì)于Scanner來(lái)說(shuō)要快一點(diǎn),因?yàn)镾canner對(duì)輸入數(shù)據(jù)進(jìn)行類解析,而B(niǎo)ufferedReader只是簡(jiǎn)單地讀取字符序列。
2、Scanner和BufferedReader都設(shè)置了緩沖區(qū),Scanner有很少的緩沖區(qū)(1KB字符緩沖)相對(duì)于BufferedReader(8KB字節(jié)緩沖),但是這是綽綽有余的。
3、BufferedReader是支持同步的,而Scanner不支持。如果我們處理多線程程序,BufferedReader應(yīng)當(dāng)使用。
4、Scanner輸入的一個(gè)問(wèn)題:在Scanner類中如果我們?cè)谌魏?個(gè)nextXXX()方法之后調(diào)用nextLine()方法,這nextLine()方法不能夠從控制臺(tái)讀取任何內(nèi)容,并且,這游標(biāo)不會(huì)進(jìn)入控制臺(tái),它將跳過(guò)這一步。nextXXX()方法包括nextInt(),nextFloat(), nextByte(),nextShort(),nextDouble(),nextLong(),next()。
在BufferReader類中就沒(méi)有那種問(wèn)題。這種問(wèn)題僅僅出現(xiàn)在Scanner類中,由于nextXXX()方法忽略換行符,但是nextLine()并不忽略它。如果我們?cè)趎extXXX()方法和nextLine()方法之間使用超過(guò)一個(gè)以上的nextLine()方法,這個(gè)問(wèn)題將不會(huì)出現(xiàn)了;因?yàn)閚extLine()把換行符消耗了。
程序示例
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輸入會(huì)遇到的問(wèn)題
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);
// 問(wèn)題原因:由于nextXXX()方法忽略換行符,但是nextLine()并不忽略它。所以如果我們?cè)趎extXXX()方法后面使用nextLine()將會(huì)出現(xiàn)問(wèn)題
// 解決方案是:在使用nextXXX()方法后,在使用nextLine()讀取下一行數(shù)據(jù)前,多使用一個(gè)nextLine()用來(lái)消耗換行符
// int intValue = sc.nextInt();
// sc.nextLine();
// String strValue = sc.nextLine();
// 或者使用BufferReader不會(huì)出現(xiàn)該問(wèn)題
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();
}
}
}

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java模擬rank/over函數(shù)實(shí)現(xiàn)獲取分組排名的方法詳解
這篇文章主要為大家詳細(xì)介紹了Java模擬rank()、over()函數(shù)獲取分組排名的方法設(shè)計(jì)及實(shí)現(xiàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下2023-04-04
Java與C++實(shí)現(xiàn)相同的MD5加密算法簡(jiǎn)單實(shí)例
下面小編就為大家?guī)?lái)一篇Java與C++實(shí)現(xiàn)相同的MD5加密算法簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-09-09
解決Spring Boot 在localhost域奇怪的404問(wèn)題(Mac book pro)
這篇文章主要介紹了解決Spring Boot 在localhost域奇怪的404問(wèn)題(Mac book pro),需要的朋友可以參考下2017-09-09
代碼詳解Java猴子選王問(wèn)題(約瑟夫環(huán))
本篇文章通過(guò)實(shí)例給大家分析了java約瑟夫環(huán)這個(gè)經(jīng)典內(nèi)容,有興趣的跟著小編一起學(xué)習(xí)下吧。2018-02-02
spring cloud升級(jí)到spring boot 2.x/Finchley.RELEASE遇到的坑
這篇文章主要介紹了spring cloud升級(jí)到spring boot 2.x/Finchley.RELEASE遇到的坑,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-08-08
Java源碼解析之SortedMap和NavigableMap
今天帶大家來(lái)學(xué)習(xí)Java SortedMap和NavigableMap,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有很好地幫助,需要的朋友可以參考下2021-05-05

