让 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();