博主在阿里筆試中拿了0分,竟是因為分不清楚 Java 輸入類 nextLine 與 next 兩個方法的區別

Geffin發表於2020-04-01

前言

以前做演算法題,都是實現一個方法,需要的引數會在方法引數中直接給出,而且需要的返回值直接在方法中 return 就好了。但是,這次阿里筆試,讓博主遭遇百萬點暴擊,需要的引數居然要到輸入流中讀取,而且返回結果居然直接輸出到控制檯上!
在這裡插入圖片描述

由於沒有見過這種套路,博主的心態極差,且十分驚奇地發現,當使用 Java 輸入類 nextLine 方法讀取輸入流中的字串時,總會莫名其妙地少讀一部分!

博主在阿里筆試中拿了0分,竟是因為分不清楚 Java 輸入類 nextLine 與 next 兩個方法的區別

然後,就沒有然後了。。。雖然博主感覺題目不算太難,但連資料都讀不到,還談啥解題呢?最終,雖然博主還是不忘初心亂寫一通,終究沒有奇蹟發生,飲恨拿下零蛋。出師未捷身先死,長使英雄淚滿襟!

讀取一個數字

既然我們要讀取輸入,肯定得用到 Scanner 類,這個類倒是挺簡單的,例如,我們需要讀取一個數字,可以這樣子設計程式。

package test;

import java.util.Scanner;

public class HelloWorld {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int i = sc.nextInt();
		System.out.println("讀取到的數字是:" + i);
    }
}

我們隨意輸入一個數字 100,控制檯的輸出也證明了我們的程式可以讀取這個數字。
在這裡插入圖片描述

博主在讀取字串上的狗血經歷

好了,重點來了!讀取數字倒沒什麼,讀取字串倒是要了博主的老命!博主在讀取資料的時候一直嘗試使用 nextLine 這個方法來讀取字串(筆試時我並不知道 next 這個方法),nextLine 這傢伙倒好,給我讀出來的資料總是缺斤少兩,真想去投訴它!

我們來還原一下現場,需求是這樣的,需要我們讀取一個數字,這個數字表示輸入字串的數量,然後下面跟著的就是一系列需要讀入的字串了,博主當時腦殘,想都沒想,大筆一揮,寫下如下程式碼:

package test;

import java.util.Scanner;

public class HelloWorld {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int i = sc.nextInt();//讀取的字串數量
		int index = 0;
		String[] array = new String [i];//存放讀取的字串
		while(index < i) {
			array[index++] = sc.nextLine();
		}
		for (String str : array) {//輸出讀取的字串
			System.out.println("輸入的字串:" + str);
		}
    }
}

理想很美好,現實很骨感,寫程式碼時光芒萬丈,檢查時卻怨天尤人。博主發現,這樣的程式碼永遠無法讀取最後一行輸入的字串,這是為啥呢?
在這裡插入圖片描述
一生要強的博主在筆試慘敗之後去查閱了 nextLine 方法的用法,發現 nextLine 可以接收空格或者 tab 鍵,其輸入以 enter 鍵結束

這倒是能解釋通了!程式在通過 nextInt 方法讀取數字之後,會留下一個 enter 鍵,這個 enter 鍵會被第一個執行的 nextLine 函式接收,這導致我們能夠讀取的資料永遠少一行(nextLine 少執行一次),同時也能解釋為什麼字串陣列第一個元素為空。

這個問題怎麼解決呢?Java 輸入類讀取字串的函式並非只有 nextLine,通過 next 也能實現類似的功能,只不過 next 與 nextLine 不同,next 不會接收回車符,tab 或者空格鍵。在我們使用 nextLine 時,需要注意前面是否有 enter 鍵,如果有,就會被 nextLine 吸收,從而造成 bug!

既然明白了 nextLine 與 next 的原理,解決問題就變得簡單了,將讀取字串的函式由 nextLine 改為 next 便可,這樣就不會吸收 nextInt 留下的 enter 鍵了。改進過的程式如下:

package test;

import java.util.Scanner;

public class HelloWorld {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int i = sc.nextInt();//讀取的字串數量
		int index = 0;
		String[] array = new String [i];//存放讀取的字串
		while(index < i) {
			array[index++] = sc.next();
		}
		for (String str : array) {//輸出讀取的字串
			System.out.println("輸入的字串:" + str);
		}
    }
}

在這裡插入圖片描述

總結

最後我們再來總結一下 nextLine 與 next 兩個方法的區別:

  1. next 不會接收回車符,tab 或者空格鍵,在接收有效資料之前會忽略這些符號,若已經讀取了有效資料,遇到這些符號會直接退出
  2. nextLine 可以接收空格或者 tab 鍵,其輸入以 enter 鍵結束

相關文章