Scanner
是Java中一个实用的文本扫描工具类(位于 java.util
包),主要用于从输入流(如键盘、文件或字符串)中解析基本数据类型和字符串。它通过正则表达式将输入分解为标记(tokens),并提供了多种方法来读取和转换这些标记。
功能 | 说明 |
---|---|
读取输入 | 从键盘、文件、字符串等来源读取数据。 |
按类型解析 | 自动将输入的文本转换为 int 、double 、String 等类型。 |
分隔符控制 | 支持自定义分隔符(默认是空白符)。 |
正则匹配 | 使用正则表达式验证或跳过特定模式的输入。 |
Scanner
可以从多种输入源构造:
构造方法 | 说明 |
---|---|
Scanner(InputStream source) |
从标准输入流(如键盘)读取,常用 System.in 。 |
Scanner(File source) |
从文件中读取数据(需处理 FileNotFoundException )。 |
Scanner(String source) |
直接解析字符串内容。 |
Scanner(Readable source) |
从任何实现了 Readable 接口的对象读取。 |
示例:
// 从键盘输入
Scanner keyboardScanner = new Scanner(System.in);
// 从字符串读取
Scanner stringScanner = new Scanner("Hello 123 45.67");
// 从文件读取(需异常处理)
try {
Scanner fileScanner = new Scanner(new File("data.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
方法 | 说明 | 示例 |
---|---|---|
nextInt() |
读取下一个 int 类型标记。 |
int num = scanner.nextInt(); |
nextDouble() |
读取下一个 double 类型标记。 |
double d = scanner.nextDouble() |
nextBoolean() |
读取下一个 boolean 类型标记。 |
boolean b = scanner.nextBoolean() |
next() |
读取下一个 String 类型标记(以空白符分隔)。 |
String s = scanner.next() |
nextLine() |
读取一行文本(包括空格,直到换行符)。 | String line = scanner.nextLine() |
示例:
Scanner scanner = new Scanner("123 45.67 true Hello");
int i = scanner.nextInt(); // 123
double d = scanner.nextDouble(); // 45.67
boolean b = scanner.nextBoolean(); // true
String s = scanner.next(); // "Hello"
方法 | 说明 |
---|---|
hasNextInt() |
检查下一个标记是否为 int 。 |
hasNextDouble() |
检查下一个标记是否为 double 。 |
hasNext() |
检查是否还有下一个标记。 |
hasNextLine() |
检查是否还有下一行。 |
示例:
Scanner scanner = new Scanner("100 ABC");
if (scanner.hasNextInt()) {
int num = scanner.nextInt(); // 不会执行,因为下一个是"ABC"
}
通过 useDelimiter()
方法设置分隔符(支持正则表达式)。
示例:按逗号分割输入
Scanner scanner = new Scanner("A,B,C,D");
scanner.useDelimiter(",");
while (scanner.hasNext()) {
System.out.println(scanner.next()); // 输出 A, B, C, D
}
使用 skip()
跳过匹配正则表达式的部分。
示例:跳过所有数字
Scanner scanner = new Scanner("Hello123World456");
scanner.skip("\\d+"); // 跳过"123"
System.out.println(scanner.next()); // 输出 "World456"
Scanner scanner = new Scanner(System.in);
System.out.print("请输入姓名:");
String name = scanner.nextLine();
System.out.print("请输入年龄:");
int age = scanner.nextInt();
System.out.println(name + "的年龄是" + age);
scanner.close(); // 关闭Scanner
String data = "John,25,New York;Alice,30,London";
Scanner scanner = new Scanner(data);
scanner.useDelimiter(";|,"); // 按分号或逗号分割
while (scanner.hasNext()) {
String name = scanner.next();
int age = scanner.nextInt();
String city = scanner.next();
System.out.println(name + " (" + age + ") - " + city);
}
scanner.close();
try (Scanner fileScanner = new Scanner(new File("data.txt"))) {
while (fileScanner.hasNextLine()) {
System.out.println(fileScanner.nextLine());
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
资源释放:
Scanner
使用了底层I/O资源,使用后需调用 close()
关闭(或用try-with-resources)。
输入阻塞:
从 System.in
读取时,程序会等待用户输入。
类型匹配:
若输入与预期类型不匹配(如用 nextInt()
读取非数字),会抛出 InputMismatchException
。
换行符问题:
nextInt()
后直接调用 nextLine()
会读取残留的换行符,需额外处理:
int num = scanner.nextInt();
scanner.nextLine(); // 消耗换行符
String line = scanner.nextLine();
场景 | Scanner | 替代方案(如BufferedReader) |
---|---|---|
键盘输入 | 简单易用,支持类型转换。 | 需手动解析字符串(如 Integer.parseInt() )。 |
文件读取 | 逐行或按标记解析方便。 | 性能更高(适合大文件)。 |
正则支持 | 内置正则分割和跳过功能。 | 需自行实现正则匹配。 |
核心用途:解析键盘输入、文件内容或字符串,支持按类型读取。
关键方法:
读取:nextInt()
, nextLine()
, next()
。
检查:hasNextInt()
, hasNextLine()
。
控制:useDelimiter()
, skip()
。
最佳实践:
始终关闭 Scanner
(用 try-with-resources
)。
处理类型不匹配异常(InputMismatchException
)。
复杂场景可结合正则表达式。