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() | 關閉掃描器(關閉底層流) |
Scanner in = new Scanner(System.in);
System.out.print("輸入姓名: ");
String name = in.next(); // 用戶輸入 "Jack" + 回車
System.out.print("輸入地址: ");
String addr = in.nextLine(); // ❌ 直接讀到空字符串 "",程序不等待輸入
next():讀取 "Jack",**停在回車符 \n 之前**,緩衝區殘留 \nnextLine():讀取**當前行剩餘內容**(即 \n),遇換行符返回空串,指針移到下一行行首in.nextLine(); // 丟棄殘留 \nString[] parts = in.nextLine().split("\\s+")// 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}+
// 文件掃描:自動關閉 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(),但極少必要
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