Java-Scanner类
Scanner
是Java中一个实用的文本扫描工具类(位于 java.util
包),主要用于从输入流(如键盘、文件或字符串)中解析基本数据类型和字符串。它通过正则表达式将输入分解为标记(tokens),并提供了多种方法来读取和转换这些标记。
1. Scanner的核心功能
功能 | 说明 |
---|---|
读取输入 | 从键盘、文件、字符串等来源读取数据。 |
按类型解析 | 自动将输入的文本转换为 int 、double 、String 等类型。 |
分隔符控制 | 支持自定义分隔符(默认是空白符)。 |
正则匹配 | 使用正则表达式验证或跳过特定模式的输入。 |
2. 构造方法
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();
}
3. 常用方法
3.1 读取基本类型
方法 | 说明 | 示例 |
---|---|---|
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"
3.2 检查输入类型
方法 | 说明 |
---|---|
hasNextInt() | 检查下一个标记是否为 int 。 |
hasNextDouble() | 检查下一个标记是否为 double 。 |
hasNext() | 检查是否还有下一个标记。 |
hasNextLine() | 检查是否还有下一行。 |
示例:
Scanner scanner = new Scanner("100 ABC");
if (scanner.hasNextInt()) {int num = scanner.nextInt(); // 不会执行,因为下一个是"ABC"
}
3.3 自定义分隔符
通过 useDelimiter()
方法设置分隔符(支持正则表达式)。
示例:按逗号分割输入
Scanner scanner = new Scanner("A,B,C,D");
scanner.useDelimiter(",");
while (scanner.hasNext()) {System.out.println(scanner.next()); // 输出 A, B, C, D
}
3.4 跳过特定模式
使用 skip()
跳过匹配正则表达式的部分。
示例:跳过所有数字
Scanner scanner = new Scanner("Hello123World456");
scanner.skip("\\d+"); // 跳过"123"
System.out.println(scanner.next()); // 输出 "World456"
4. 典型应用场景
4.1 从键盘读取用户输入
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
4.2 解析结构化文本
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();
4.3 读取文件内容
try (Scanner fileScanner = new Scanner(new File("data.txt"))) {while (fileScanner.hasNextLine()) {System.out.println(fileScanner.nextLine());}
} catch (FileNotFoundException e) {e.printStackTrace();
}
5. 注意事项
-
资源释放:
Scanner
使用了底层I/O资源,使用后需调用close()
关闭(或用try-with-resources)。 -
输入阻塞:
从System.in
读取时,程序会等待用户输入。 -
类型匹配:
若输入与预期类型不匹配(如用nextInt()
读取非数字),会抛出InputMismatchException
。 -
换行符问题:
nextInt()
后直接调用nextLine()
会读取残留的换行符,需额外处理:int num = scanner.nextInt(); scanner.nextLine(); // 消耗换行符 String line = scanner.nextLine();
6. 与替代方案的对比
场景 | Scanner | 替代方案(如BufferedReader) |
---|---|---|
键盘输入 | 简单易用,支持类型转换。 | 需手动解析字符串(如 Integer.parseInt() )。 |
文件读取 | 逐行或按标记解析方便。 | 性能更高(适合大文件)。 |
正则支持 | 内置正则分割和跳过功能。 | 需自行实现正则匹配。 |
7. 总结
-
核心用途:解析键盘输入、文件内容或字符串,支持按类型读取。
-
关键方法:
-
读取:
nextInt()
,nextLine()
,next()
。 -
检查:
hasNextInt()
,hasNextLine()
。 -
控制:
useDelimiter()
,skip()
。
-
-
最佳实践:
-
始终关闭
Scanner
(用try-with-resources
)。 -
处理类型不匹配异常(
InputMismatchException
)。 -
复杂场景可结合正则表达式。
-