首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

Java Scanner 類完全指南:構造器、分隔符、next/nextLine 陷阱與最佳實踐

     編輯:Java 綜合教學

Scanner 類核心用法與避坑指南:從標準輸入到文件解析

java.util.Scanner 是 Java 基礎 I/O 最常用的掃描器,支援正則分隔、類型轉換、流/文件/字符串多源輸入。本文系統整理構造器、核心方法、分隔符定製、next() 與 nextLine() 經典陷阱,並給出生產級使用模板。

一、三大構造器:多源輸入無縫切換

// 1. 標準輸入(控制台)
Scanner in = new Scanner(System.in);

// 2. 文件輸入(自動關閉需 try-with-resources)
Scanner fileIn = new Scanner(new File("data.txt"), StandardCharsets.UTF_8);

// 3. 字符串輸入(單元測試/解析神器)
Scanner strIn = new Scanner("name=Jack;age=25;city=NY");

二、核心方法速查表

分類方法說明
判斷hasNext()是否有下一個 token(默認按空白分隔)
hasNextInt() / hasNextDouble() ...按類型預判
hasNext(Pattern)按正則預判
hasNextLine()是否有下一行(含空行)
讀取next()讀下一個 token(跳過分隔符,遇分隔符停止)
nextLine()讀整行(含前導空白,**不跳過**分隔符,讀到換行符)
nextInt() / nextDouble() ...按類型讀取並轉換
next(Pattern)按正則讀取
nextByte/Short/Long/Float/Boolean/BigInteger/BigDecimal基本類型全覆蓋
其他useDelimiter(Pattern)修改分隔符(影響 next/nextInt 等,不影響 nextLine)
delimiter()獲取當前分隔符 Pattern
close()關閉掃描器(關閉底層流)

三、經典陷阱:next() 後調用 nextLine() 讀到空行

現象復現

Scanner in = new Scanner(System.in);
System.out.print("輸入姓名: ");
String name = in.next();        // 用戶輸入 "Jack" + 回車
System.out.print("輸入地址: ");
String addr = in.nextLine();    // ❌ 直接讀到空字符串 "",程序不等待輸入

根因分析

  • next():讀取 "Jack",**停在回車符 \n 之前**,緩衝區殘留 \n
  • nextLine():讀取**當前行剩餘內容**(即 \n),遇換行符返回空串,指針移到下一行行首

三種解決方案

  1. 額外消費換行符:in.nextLine(); // 丟棄殘留 \n
  2. 統一用 nextLine() + 手動解析:String[] parts = in.nextLine().split("\\s+")
  3. 統一用 next() 讀 token:地址無空格時可行

四、分隔符定製實戰:解析 CSV / Key=Value

// 1. CSV 解析(逗號分隔,支援引號內逗號需更複雜正則)
Scanner csv = new Scanner("Jack,25,New York");
csv.useDelimiter(",");                    // 或 Pattern.compile(",")
while (csv.hasNext()) System.out.println(csv.next().trim());

// 2. Key=Value 解析(分號分隔,等號分鍵值)
Scanner kv = new Scanner("name=Jack;age=25;city=NY");
kv.useDelimiter(";");                     // 先按分號切 token
while (kv.hasNext()) {
    String[] pair = kv.next().split("="); // 再按等號切鍵值
    System.out.println(pair[0] + " -> " + pair[1]);
}

// 3. 獲取默認分隔符(\p{javaWhitespace}+,即一個或多個空白字符)
System.out.println(in.delimiter()); // 輸出 \p{javaWhitespace}+

五、資源管理鐵律:try-with-resources

// 文件掃描:自動關閉 FileInputStream
try (Scanner sc = new Scanner(new File("data.txt"), "UTF-8")) {
    while (sc.hasNextLine()) {
        System.out.println(sc.nextLine());
    }
} // 隱式 sc.close(),即使拋異常也會關閉

// 標準輸入:通常不關閉 System.in(關閉後無法重開)
Scanner console = new Scanner(System.in);
// 程序結束前可調用 console.close(),但極少必要

六、性能提示:大文件解析優先 BufferedReader + split

Scanner 內部編譯正則、逐字符掃描,大文件(>100MB)解析較慢。高性能場景:

try (BufferedReader br = Files.newBufferedReader(path, StandardCharsets.UTF_8)) {
    String line;
    while ((line = br.readLine()) != null) {
        String[] fields = line.split(",");
        // 處理 fields
    }
}

七、總結

  • 構造器三選一:System.in、File、String
  • 默認分隔符:空白字符(\\p{javaWhitespace}+)
  • 核心陷阱:next() 留下換行符 → nextLine() 讀空行,必須額外消費或統一用 nextLine()
  • useDelimiter() 不影響 nextLine()
  • 文件/流輸入**必須** try-with-resources 關閉
  • 大文件高性能解析改用 BufferedReader
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved