public static int getChoice(@NotNull Scanner scanner) {
while (true) {
// 判断输入是否为整数
if (scanner.hasNextInt()) {
int choice = scanner.nextInt();
if (choice >= 1 && choice <= 4) {
return choice;
} else {
System.out.println("Your choice is out of range, please try again.");
}
} else {
System.out.println("Your choice is illegal, please try again.");
// 清空输入缓冲区
scanner.next();
}
}
}
为了实现这个需求,我们需要知道这些事情:
①当使用Scanner要求用户输入时,用户输入的内容,无论是什么,都会先被保存到缓冲区。
②hasNextxxx()方法用于检测缓冲区的内容是否可以被解析为某种形式,但这些方法并不对缓冲区中的内容进行任何处理。
③nextxxx()方法将缓冲区中的内容解析为某种形式并返回,这个操作会清空缓冲区。但如果缓冲区内容无法被正确解析,则会报错。
因此,我们需要做如下操作来实现这个需求:
①判断缓冲区内容是否可以被解析为整数(通过hasNextInt()方法)
-----为什么我们不直接使用nextInt()接收?因为如果用户的输入不是整数,那么程序就会报错。
②如果用户输入的是整数,即hasNextInt()方法返回true,我们就用choice接收这个整数(通过nextInt()方法)。如果choice值在指定范围内,则将其返回;否则我们输出提示,要求用户再次输入。
③如果用户输入的不是整数,我们使用next()方法清空缓冲区,并提示用户再次输入。
-----为什么next()方法可以清空缓冲区?事实上,next()方法是解析缓冲区内容为字符串(不管用户输入的是什么乱七八糟的东西,都可以被当成字符串)并返回,不过我们并没有使用任何变量去接收这个返回(我们也不需要这个非法的输入)。我们只需要知道,这个操作把缓冲区内容清空并返回了,这就够了。
-----为什么用户输入的不是整数时需要清空缓冲区,而输入的不在指定范围时不需要这个操作来清空缓冲区?因为用户输入的不是整数时,如果我们不清空缓冲区,那么下一次循环时,hasNextInt()方法仍然无法将缓冲区内容解析为整数,从而程序进入死循环。而用户输入的整数不在指定范围内时,由于他是整数,这个整数一定会被choice接收,当它被choice接收后,缓冲区里面就没有内容了。总之,我们需要保证,在输入不合法时,用户在下一次输入时缓冲区里面是没有内容的。
因此,要求输入指定内容的浮点数、字母,以至于字符串,都可按照这个思路来解决,关键在于在下一次输入前,必须要清空缓冲区。