Java Scanner 类
Scanner类是Java中一个非常使用的工具类,位于java.util包中,主要用于解析基本类型和字符串的简单文本扫描器。接下来会进行详细讲解,若有不足,欢迎提出!!!
一、Scanner类概述
Scanner类可以讲输入(通常是文件或键盘输入)分解为标记(Tokens),然后使用各种next方法将这些标记转换为不同类型的值。它使用正则表达式来解析基本类型和字符串。
核心功能
- 多输入源支持:支持控制台、文件、字符串、输入流等多种输入源;
- 数据类型解析:能将输入解析为各种基本类型和字符串;
- 正则表达式支持:可以使用正则表达式进行模式匹配和分隔;
- 本地化支持:支持不同地区的数据格式;
- 输入验证:提供hasNext系列方法进行输入验证。
二、创建Scanner对象
Scanner有多个构造函数,可以从不同的数据来源读取数据。
- 从标准输入读取;
- 从字符串读取;
- 从文件读取(需要处理IOException);
- 从输入流创建;
- 从Readable对象创建。
更多的是使用方法一和方法三。
java
// 1. 从标准输入创建
Scanner stdinScanner = new Scanner(System.in);
// 2. 从字符串创建
Scanner stringScanner = new Scanner("Text 123 45.67");
// 3. 从文件创建(需处理异常)
try {
Scanner fileScanner = new Scanner(new File("data.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
// 4. 从输入流创建
Scanner streamScanner = new Scanner(inputStream);
// 5. 从Readable对象创建
Scanner readableScanner = new Scanner(readableObject);
进行配置
java
// 设置分隔符(支持正则表达式)
scanner.useDelimiter(","); // 简单分隔符
scanner.useDelimiter("\\s*,\\s*"); // 允许分隔符前后有空格
// 设置区域(影响数字解析格式)
scanner.useLocale(Locale.US); // 使用点作为小数点
scanner.useLocale(Locale.FRENCH); // 使用逗号作为小数点
// 设置基数(用于数字解析)
scanner.useRadix(16); // 设置为16进制模式
三、数据读取方法
方法类型 | 包含方法 | 说明 |
---|---|---|
整数类型 | nextByte() , nextShort() , nextInt() , nextLong() |
读取各种整数 |
浮点类型 | nextFloat() , nextDouble() |
读取浮点数 |
大数类型 | nextBigInteger() , nextBigDecimal() |
读取大数 |
布尔类型 | nextBoolean() |
读取布尔值 |
字符串类型 | next() , nextLine() |
读取字符串 |
关键区别点
- 输入消耗行为
- 跳过前导的分隔符(默认是空白字符);
- 跳过匹配目标类型的内容;
- 不会消耗后面的分隔符。
特殊案例:
- nextLine() 会读取直到行尾并消耗换行符;
- 其余的方法读取后,后面如果跟nextLine()会读到空行
java
Scanner scanner = new Scanner("123\n456");
int num = scanner.nextInt(); // 读取123,不消耗\n
String line = scanner.nextLine(); // 读取空字符串(因为读取了\n)
3.1 整数读取
方法 | 返回类型 | 取值范围 | 基数支持 | 特点 |
---|---|---|---|---|
nextByte() |
byte | -128 ~ 127 | 支持 | 读取字节型整数 |
nextShort() |
short | -32768 ~ 32767 | 支持 | 读取短整型 |
nextInt() |
int | -2³¹ ~ 2³¹-1 | 支持 | 最常用的整数读取方法 |
nextLong() |
long | -2⁶³ ~ 2⁶³-1 | 支持 | 读取长整型 |
1. nextInt() - 最常用的整数读取方法
功能: 读取一个32位有符号整数。 示例:
java
Scanner scanner = new Scanner(System.in);
System.out.print("请输入一个整数: ");
int number = scanner.nextInt();
System.out.println("您输入的数是: " + number);
特点
- 默认解析十进制数字;
- 遇到非数字字符时停止读取;
- 会跳过前导空白字符;
- 不消耗数字后面的分隔符。
注意事项
java
// 问题代码示例
int a = scanner.nextInt();
int b = scanner.nextInt();
// 如果输入"123 456"可以正常工作
// 但如果输入"123,456"会抛出InputMismatchException
// 解决方案:设置正确分隔符
scanner.useDelimiter(",");
2. nextLong()
功能:读取64位有符号长整数
使用场景:
- 需要读取超过21亿的数字时;
- 处理大ID号、时间戳等。
java
System.out.print("请输入长整型ID: ");
long id = scanner.nextLong();
System.out.println("ID是: " + id);
3. nextByte() & nextShort() - 读取小范围整数
使用场景:
- 明确知道输入数字范围较小时;
- 需要自动范围检查时。
示例
java
System.out.print("请输入年龄(0-127): ");
byte age = scanner.nextByte(); // 自动检查范围
特点
- 如果输入超出类型范围,抛出
InputMismatchException
- 适合读取配置参数等小范围数字。
3.2 浮点类型
方法 | 返回类型 | 存储大小 | 精度 | 取值范围 | 特点 |
---|---|---|---|---|---|
nextFloat() |
float | 32位 | 6-7位有效数字 | ±1.4E-45 ~ ±3.4E+38 | 读取单精度浮点数 |
nextDouble() |
double | 64位 | 15-16位有效数字 | ±4.9E-324 ~ ±1.8E+308 | 读取双精度浮点数(默认推荐) |
基本使用示例
java
Scanner scanner = new Scanner(System.in);
// 读取单精度浮点数
System.out.print("请输入浮点数(float): ");
float fValue = scanner.nextFloat();
// 读取双精度浮点数
System.out.print("请输入浮点数(double): ");
double dValue = scanner.nextDouble();
System.out.println("读取结果: float=" + fValue + ", double=" + dValue);
3.3 大数类型
1. nextBigImteger()方法
功能说明:
读取输入中的下一个标记(token)并将其转换为BigInteger
对象。BigInteger
可以表示任意精度的整数,适用于超出long
类型范围的超大整数。
注意事项
- 输入必须是一个有效的整数表示
- 可以处理任意长度的整数(只要内存允许)
- 如果输入不是有效的整数格式,会抛出
InputMismatchException
- 建议先使用
hasNextBigInteger()
进行检查 - 默认使用十进制,可以通过参数指定其他进制
java
import java.util.Scanner;
import java.math.BigInteger;
public class BigIntegerExample {
public static void main(String[] args) {
// 示例1:基本用法
Scanner scanner1 = new Scanner("12345678901234567890");
BigInteger bigInt1 = scanner1.nextBigInteger();
System.out.println("十进制大整数: " + bigInt1);
// 示例2:指定进制
Scanner scanner2 = new Scanner("FF");
BigInteger bigInt2 = scanner2.nextBigInteger(16); // 16进制
System.out.println("十六进制FF转为十进制: " + bigInt2);
// 示例3:超大整数运算
Scanner scanner3 = new Scanner("9999999999999999999999999999999999999999");
BigInteger a = scanner3.nextBigInteger();
BigInteger b = new BigInteger("1111111111111111111111111111111111111111");
System.out.println("a + b = " + a.add(b));
}
}
2. nextBigDecimal()方法
功能说明:
读取输入中的下一个标记(token)并将其转换为BigDecimal
对象。BigDecimal
可以表示任意精度的十进制数,适用于需要高精度计算的场景,如金融计算。
注意事项:
- 输入必须是一个有效的十进制数表示(可以包含小数点)
- 可以处理任意精度的十进制数
- 如果输入不是有效的数字格式,会抛出
InputMismatchException
- 建议先使用
hasNextBigDecimal()
进行检查 - 特别适合金融计算等需要精确小数运算的场景
java
import java.util.Scanner;
import java.math.BigDecimal;
public class BigDecimalExample {
public static void main(String[] args) {
// 示例1:基本用法
Scanner scanner1 = new Scanner("1234567890.1234567890");
BigDecimal bigDec1 = scanner1.nextBigDecimal();
System.out.println("高精度小数: " + bigDec1);
// 示例2:精确计算
Scanner scanner2 = new Scanner("0.1");
BigDecimal a = scanner2.nextBigDecimal();
BigDecimal b = new BigDecimal("0.2");
System.out.println("0.1 + 0.2 = " + a.add(b)); // 输出0.3,而非浮点数的近似值
// 示例3:金融计算
Scanner scanner3 = new Scanner("10000000000.0000000001");
BigDecimal principal = scanner3.nextBigDecimal();
BigDecimal rate = new BigDecimal("0.05"); // 5%利率
BigDecimal interest = principal.multiply(rate);
System.out.println("利息: " + interest);
}
}
相关检查方法 hasNextBigInteger()
- 检查洗一个标记是否可以解释为
BigInteger
- 有重载方法可以指定进制:
hasNextBigInteger(int radix)
示例:
java
Scanner scanner = new Scanner("12345678901234567890");
if(scanner.hasNextBigInteger()) {
BigInteger num = scanner.nextBigInteger();
}
hasNextBigDecimal()
- 检查下一个标记是否可以解释为
BigDecimal
示例:
java
Scanner scanner = new Scanner("123.456789");
if(scanner.hasNextBigDecimal()) {
BigDecimal num = scanner.nextBigDecimal();
}
综合示例:
java
import java.util.Scanner;
import java.math.BigInteger;
import java.math.BigDecimal;
public class BigNumberDemo {
public static void main(String[] args) {
String input = "987654321098765432109876543210 3.141592653589793238462643383279";
try (Scanner scanner = new Scanner(input)) {
// 读取超大整数
if (scanner.hasNextBigInteger()) {
BigInteger hugeInt = scanner.nextBigInteger();
System.out.println("超大整数: " + hugeInt);
System.out.println("平方: " + hugeInt.pow(2));
}
// 读取高精度小数
if (scanner.hasNextBigDecimal()) {
BigDecimal pi = scanner.nextBigDecimal();
System.out.println("圆周率近似值: " + pi);
System.out.println("乘以2: " + pi.multiply(new BigDecimal("2")));
}
}
}
}
使用场景建议
-
nextBigInteger()
适用场景:- 处理超过long范围的整数(大于2^63-1或小于-2^63)
- 加密算法中的大数运算
- 需要精确整数计算的场合
-
nextBigDecimal()
适用场景:- 金融计算(货币、利率等)
- 科学计算需要高精度小数的场合
- 避免浮点数精度问题的任何计算
-
性能考虑
- BigInteger/BigDecimal比基本类型慢
- 只在必要时使用
- 对于已知范围内的数,优先使用基本类型
-
异常处理
- 总是检查hasNext...()方法
- 捕获可能的InputMismatchException
- 使用try-with-resources确保Scanner关闭
3.4 布尔类型
nextBoolean()
方法
- 方法功能
Boolean()是Scanner类的一个实例方法,用于从输入源读取下一个标记(token)并将其解析为boolean值。
核心功能:
- 读取输入中的下一个有效标记;
- 将其转换为boolean值;
- 返回转换后的boolean值。
- 返回值:
返回解析后的boolean值:
- 当输入为"true"(不区分大小写)时返回
true
- 当输入为"false"(不区分大小写)时返回
false
-
工作原理:
- 首先跳过输入中的任何前导空白字符
- 读取下一个完整的标记(token)
- 将标记与"true"和"false"比较(不区分大小写)
- 返回匹配的boolean值
-
注意事项
4.1 有效输入格式:
-
接受的值:
- "true"(任何大小写组合,如True、TRUE、tRuE)
- "false"(任何大小写组合,如False、FALSE、fAlSe)
-
不接受的值:
- 任何其他字符串(包括"1"/"0"、"yes"/"no"等)
- 空字符串或空白字符
4.2 异常情况:
-
InputMismatchException:当下一个标记不能转换为boolean值时抛出
-
IllegalStateException:当Scanner已关闭时调用此方法
-
NoSuchElementException:当输入已耗尽时调用此方法
4.3 最佳实践
- 总是先使用
hasNextBoolean()
进行检查 - 处理可能的异常
- 考虑用户输入的各种情况(大小写、前后空格等)
- 总是先使用
示例:
java
Scanner scanner = new Scanner("true false TRUE False tRuE fAlSe");
while(scanner.hasNextBoolean()) {
System.out.println(scanner.nextBoolean());
}
// 输出:
// true
// false
// true
// false
// true
// false
3.5 字符串类型
1.next()
方法
1.1 方法功能 next()
方法用于从输入源读取并返回下一个完整的标记(token),默认以空白字符作为分隔符。
1.2 工作原理
- 跳过输入中的前导空白字符(空格、制表符、换行符等)
- 读取字符直到遇到下一个分隔符(默认是空白字符)
- 返回读取到的字符串(不包含分隔符)
1.3 重要特性
- 分隔符 :默认使用空白字符(
\s+
)作为分隔符 - 阻塞行为:当从System.in读取时,如果没有输入会阻塞等待
- 标记边界:遇到分隔符即停止读取
- 大小写敏感:保留原始大小写
示例:
java
Scanner scanner = new Scanner("Hello World!\nJava Scanner");
System.out.println(scanner.next()); // 输出: Hello
System.out.println(scanner.next()); // 输出: World!
System.out.println(scanner.next()); // 输出: Java
1.6 注意事项
- 输入等待:从控制台读取时会阻塞等待用户输入;
- 异常情况:
NoSuchElementException
:输入已耗尽时抛出IllegalStateException
:Scanner已关闭时抛出
- 分隔符处理:不会包含分隔符在返回值中;
- 前导空白:不会跳过前导空白字符。
1.7 典型应用场景
- 读取以空格分隔的单词
- 处理结构化的文本数据
- 需要逐个标记处理的输入
2. nextLine()
方法
2.1 方法功能 nextLine()
方法读取从当前位置到行尾的所有字符(包括空格但不包括最后的换行符),返回一个字符串
2.2 工作原理
- 从当前位置开始读取
- 包含所有字符直到遇到行终止符(
\n
、\r
或\r\n
) - 返回读取到的字符串(不包含行终止符)
- 将Scanner位置移动到下一行开头
2.3 重要特性
- 行终止符:识别各种系统的行结束符
- 内容包含:读取包括空格在内的所有字符
- 位置移动:读取后位置移动到下一行开头
- 空行处理:可以返回空字符串("")
示例:
java
Scanner scanner = new Scanner("第一行文本\n第二行文本\n\n第四行文本");
System.out.println("[" + scanner.nextLine() + "]"); // [第一行文本]
System.out.println("[" + scanner.nextLine() + "]"); // [第二行文本]
System.out.println("[" + scanner.nextLine() + "]"); // [] (空行)
System.out.println("[" + scanner.nextLine() + "]"); // [第四行文本]
2.4 注意事项
- 换行符处理:消耗但不包含行终止符
- 混合使用问题 :与
next()
系列方法混用需谨慎 - 空行返回:会返回空字符串而非null
- 控制台输入:从控制台读取时会阻塞等待用户输入回车
2.5 典型应用场景
- 读取用户输入的整行文本
- 处理包含空格的完整句子
- 读取配置文件中的整行内容
- 处理多行文本数据
next()
VS nextLine()
特性 | next() |
nextLine() |
---|---|---|
读取单位 | 标记(token) | 整行 |
分隔符 | 空白字符 | 行终止符 |
包含空格 | 否 | 是 |
前导空白处理 | 自动跳过 | 保留 |
典型返回值 | "Hello" | "Hello World" |
输入" a b "的结果 | "a" (两次调用得到"a"和"b") | " a b " |
换行符处理 | 作为分隔符跳过 | 作为行结束符消耗 |