让 Java 扫描仪中的 keyboardIn.nextInt() 忽略“$”符号而不改变 .nextInt 的最佳方法是什么?
What is the best way to have keyboardIn.nextInt() in Java Scanner to ignore a '$' sign without altering .nextInt?
这就是我目前所拥有的!
int downPayment;
System.out.printf("How much will the down payment be?: ");
Scanner keyboardIn = new Scanner(System.in);
downPayment = keyboardIn.nextInt();
System.out.println(downPayment);
但是,如果我要让用户输入“$500”,构建将会失败(因为扫描器 'scans' 仅用于整数)。
有没有一种方法可以在忽略 'integer' 的第一个索引的情况下使用扫描仪,因为我认为让扫描仪将变量视为字符串并在追加时将美元值转换为 int第一个索引非常低效。
谢谢!
您可以使用以下之一:
downPayment = Integer.parseInt(keyboardIn.next().replace("$",""));
downPayment = Integer.parseInt(keyboardIn.next().substring(1));
但我不知道是不是"best way"。
如果你真的必须保留你的 nextInt(),你可以捕获异常:
try {
downPayment = keyboardIn.nextInt();
} catch (InputMismatchException ex) {
// handle it
downPayment = Integer.parseInt(keyboardIn.next().replace("$",""));
}
但我认为通常不建议处理任何 RuntimeException。
这显然不能处理所有情况,但您可以检查第一个值是否为 '$' 字符,如果是则将其删除,然后检查剩余的字符串是否可以解析为 int:
public static void getDownPaymentValue() {
Scanner sc = new Scanner(System.in);
System.out.print("How much will the down payment be?: ");
String input = sc.next();
String validatedInput = validateUserInput(input);
int downPayment = 0;
if(isInteger(validatedInput)) {
downPayment = Integer.parseInt(validatedInput);
} else {
System.out.println("Value is not of type int.");
}
System.out.println("Validated input is: " + validatedInput);
}
public static String validateUserInput(String str) {
int dollarSignIndex = str.indexOf("$");
if(dollarSignIndex == 0) {
str = str.substring(1);
}
return str;
}
public static boolean isInteger(String str) {
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
与其让您的程序适用于在数字开头输入美元符号的用户,一种选择是更清楚地告诉用户他们应该只输入数字本身。如果在提示末尾放置一个 $
符号,用户将在 $
之后立即输入;任何明智的用户都会意识到他们不应该输入额外的 $
,因为在屏幕上将两个 $
符号并排显示是明显错误的。
如果有人愚蠢到输入额外的 $
,让他们看到一条错误消息。
System.out.print("How much will the down payment be?: $");
一个简单的改变。另请注意,您在这里不需要 printf
,只需 print
就足够了。
I think that having scanner look at the variable as a string and converting the dollar value to an int while appending the first index is super inefficient.
从思考中得出结论是哲学家的事,不是工程师的事。
这是您建议的高效版本:
import java.util.*;
class NextInt {
public static void main(String[] args) {
Scanner keyboardIn = new Scanner(System.in);
int downPayment;
for(int i=0; i<10000000; i++) {
downPayment = keyboardIn.nextInt();
}
}
}
这是您建议的超级低效版本:
import java.util.*;
class AsString {
public static void main(String[] args) {
Scanner keyboardIn = new Scanner(System.in);
int downPayment;
for(int i=0; i<10000000; i++) {
String input = keyboardIn.next();
if (input.startsWith("$")) input = input.substring(1);
downPayment = Integer.parseInt(input);
}
}
}
我们可以生成1000万行测试数据:
yes '1500' | head -n 10000000 > nodollar
yes '0' | head -n 10000000 > dollar
现在对其进行基准测试(三者中最好的):
$ time java NextInt < nodollar
real 0m3.544s
user 0m3.759s
sys 0m0.124s
$ time java AsString < dollar
real 0m2.530s
user 0m2.735s
sys 0m0.111s
事实证明,我们不仅在谈论每次用户输入节省约 0.4 微秒的时间上限,而且您正在将时间和精力花在 更慢的 实施上.难怪他们说过早的优化是万恶之源!
无论如何,这是一个切线问题,实际上并没有回答这个问题。您是否考虑过使用 skip
来跳过可选的 $
?
keyboardIn.skip("[$]?");
downPayment = keyboardIn.nextInt();
这就是我目前所拥有的!
int downPayment;
System.out.printf("How much will the down payment be?: ");
Scanner keyboardIn = new Scanner(System.in);
downPayment = keyboardIn.nextInt();
System.out.println(downPayment);
但是,如果我要让用户输入“$500”,构建将会失败(因为扫描器 'scans' 仅用于整数)。
有没有一种方法可以在忽略 'integer' 的第一个索引的情况下使用扫描仪,因为我认为让扫描仪将变量视为字符串并在追加时将美元值转换为 int第一个索引非常低效。
谢谢!
您可以使用以下之一:
downPayment = Integer.parseInt(keyboardIn.next().replace("$",""));
downPayment = Integer.parseInt(keyboardIn.next().substring(1));
但我不知道是不是"best way"。
如果你真的必须保留你的 nextInt(),你可以捕获异常:
try {
downPayment = keyboardIn.nextInt();
} catch (InputMismatchException ex) {
// handle it
downPayment = Integer.parseInt(keyboardIn.next().replace("$",""));
}
但我认为通常不建议处理任何 RuntimeException。
这显然不能处理所有情况,但您可以检查第一个值是否为 '$' 字符,如果是则将其删除,然后检查剩余的字符串是否可以解析为 int:
public static void getDownPaymentValue() {
Scanner sc = new Scanner(System.in);
System.out.print("How much will the down payment be?: ");
String input = sc.next();
String validatedInput = validateUserInput(input);
int downPayment = 0;
if(isInteger(validatedInput)) {
downPayment = Integer.parseInt(validatedInput);
} else {
System.out.println("Value is not of type int.");
}
System.out.println("Validated input is: " + validatedInput);
}
public static String validateUserInput(String str) {
int dollarSignIndex = str.indexOf("$");
if(dollarSignIndex == 0) {
str = str.substring(1);
}
return str;
}
public static boolean isInteger(String str) {
try {
Integer.parseInt(str);
return true;
} catch (NumberFormatException e) {
return false;
}
}
与其让您的程序适用于在数字开头输入美元符号的用户,一种选择是更清楚地告诉用户他们应该只输入数字本身。如果在提示末尾放置一个 $
符号,用户将在 $
之后立即输入;任何明智的用户都会意识到他们不应该输入额外的 $
,因为在屏幕上将两个 $
符号并排显示是明显错误的。
如果有人愚蠢到输入额外的 $
,让他们看到一条错误消息。
System.out.print("How much will the down payment be?: $");
一个简单的改变。另请注意,您在这里不需要 printf
,只需 print
就足够了。
I think that having scanner look at the variable as a string and converting the dollar value to an int while appending the first index is super inefficient.
从思考中得出结论是哲学家的事,不是工程师的事。
这是您建议的高效版本:
import java.util.*;
class NextInt {
public static void main(String[] args) {
Scanner keyboardIn = new Scanner(System.in);
int downPayment;
for(int i=0; i<10000000; i++) {
downPayment = keyboardIn.nextInt();
}
}
}
这是您建议的超级低效版本:
import java.util.*;
class AsString {
public static void main(String[] args) {
Scanner keyboardIn = new Scanner(System.in);
int downPayment;
for(int i=0; i<10000000; i++) {
String input = keyboardIn.next();
if (input.startsWith("$")) input = input.substring(1);
downPayment = Integer.parseInt(input);
}
}
}
我们可以生成1000万行测试数据:
yes '1500' | head -n 10000000 > nodollar
yes '0' | head -n 10000000 > dollar
现在对其进行基准测试(三者中最好的):
$ time java NextInt < nodollar
real 0m3.544s
user 0m3.759s
sys 0m0.124s
$ time java AsString < dollar
real 0m2.530s
user 0m2.735s
sys 0m0.111s
事实证明,我们不仅在谈论每次用户输入节省约 0.4 微秒的时间上限,而且您正在将时间和精力花在 更慢的 实施上.难怪他们说过早的优化是万恶之源!
无论如何,这是一个切线问题,实际上并没有回答这个问题。您是否考虑过使用 skip
来跳过可选的 $
?
keyboardIn.skip("[$]?");
downPayment = keyboardIn.nextInt();