来自字符串的数值
Numeric values from a String
我正在创建一个物理计算器,目前正在研究平均速度。对于位移,我希望用户输入一个字符串,即“5km north”。然后使用一种方法仅使用 Double.parseDouble 或类似方法将字符串中的数值分配为双精度值。
下面是我提取数值的方法
private double getNumericalValue(String userInput) {
double numericalOutput = 0.0;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) >= 65 && userInput.charAt(i) <= 122) {
numericalOutput = Double.parseDouble(userInput.substring(0, i));
}
}
return numericalOutput;
}
最后是 getAverageVelocity 方法
private void getAverageVelocity() {
// formula average velocity = displacement s / change in time t
double avgVelocity = 0.0;
System.out.println("Enter the displacement: [ex. 5 km north]");
String displacement = getStringInput();
System.out.println("Enter the change in time: [ex. 1 hour]");
String changeInTime = getStringInput();
// parse the string and change numerical input into double
double numericalS = getNumericalValue(displacement);
double numericalT = getNumericalValue(changeInTime);
avgVelocity = numericalS / numericalT;
System.out.println("The Average Velocity is: " + avgVelocity);
}
如您所见,我想我可以简单地将字符与其 ascii 值进行比较。但是,它在我的双输出中包含 k 或 space,这会引发此错误。
Exception in thread "main" java.lang.NumberFormatException: For input string: "5 k"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:556)
at Main.getNumericalValue(Main.java:122)
at Main.getAverageVelocity(Main.java:393)
at Main.kineticsIn1DCalculator(Main.java:375)
at Main.performAction(Main.java:141)
at Main.runner(Main.java:29)
at Main.main(Main.java:22)
任何帮助和详尽的解释都会很棒。谢谢
你有错误,因为即使找到第一个数字,for
循环仍在继续。您只需添加 break
指令,然后 for 循环在找到的第一个数字处结束。
这是方法的最终代码getNumericalValue
:
private double getNumericalValue(String userInput) {
double numericalOutput = 0.0;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) >= 65 && userInput.charAt(i) <= 122) {
numericalOutput = Double.parseDouble(userInput.substring(0, i));
break;
}
}
return numericalOutput;
}
您只需输入该行并解析其部分。
最好引入一个class来保存一个带单位的值,其中“km north”算作一个单位。
因为 java 14 存在 record
class.
record ValueWithUnit(double value, String unit) {
public static ValueWithUnit from(String s) {
String v = s.replaceFirst("^(.*?)([ A-z].*)$", "");
String u = s.replaceFirst("^(.*?)([ A-z].*)$", "");
if (u == v) {
u = "";
}
double x = Double.parseDouble(v); // Replaces getNumericalValue(v);
return new Value(x, u);
}
@Override
public String toString() {
String.format("%f %s", value, unit);
}
}
您可以直接将其用作:
ValueWithUnit vu = new ValueWithUnit(30.0, "km");
System.out.println(vu);
代码则变为:
private void getAverageVelocity() {
// formula average velocity = displacement s / change in time t
double avgVelocity = 0.0;
System.out.println("Enter the displacement: [ex. 5 km north]");
ValueWithUnit displacement = ValueWithUnit.from(getStringInput());
System.out.println("Enter the change in time: [ex. 1 hour]");
ValueWithUnit changeInTime = ValueWithUnit.from(getStringInput());
// parse the string and change numerical input into double
double numericalS = displacement.value;
double numericalT = changeInTime.value;
avgVelocity = numericalS / numericalT;
System.out.printf("The Average Velocity is: %f %s%n", avgVelocity,
displacement.unit + "/" + changeInTime.unit);
}
你在 if 块中实际测试的是 i 处的字符是否是字母 A-Z、a-z 和其他符号(即 [ ^ ], ...etc) 检查它是否是一个数字(即 0-9)对应的十进制范围是 48-57 check this link
至于异常是因为 substring(0, 0) 会产生一个空字符串,当试图解析它时,Double.parseDouble() 会抛出异常。
这是您可以使用的解决方案:
private double getNumericalValue(String userInput) {
double numericalOutput = 0.0;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) >= 48 && userInput.charAt(i) <= 57) {
numericalOutput = Double.parseDouble(userInput.substring(0, i + 1));
}
}
return numericalOutput;
}
注:substring(i, j) i 含,j 不含
更新:
刚刚注意到,在你的情况下发生异常是因为你试图解析字母“k”因为它通过了条件,导致 Double.parseDouble() 抛出异常。
我正在创建一个物理计算器,目前正在研究平均速度。对于位移,我希望用户输入一个字符串,即“5km north”。然后使用一种方法仅使用 Double.parseDouble 或类似方法将字符串中的数值分配为双精度值。
下面是我提取数值的方法
private double getNumericalValue(String userInput) {
double numericalOutput = 0.0;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) >= 65 && userInput.charAt(i) <= 122) {
numericalOutput = Double.parseDouble(userInput.substring(0, i));
}
}
return numericalOutput;
}
最后是 getAverageVelocity 方法
private void getAverageVelocity() {
// formula average velocity = displacement s / change in time t
double avgVelocity = 0.0;
System.out.println("Enter the displacement: [ex. 5 km north]");
String displacement = getStringInput();
System.out.println("Enter the change in time: [ex. 1 hour]");
String changeInTime = getStringInput();
// parse the string and change numerical input into double
double numericalS = getNumericalValue(displacement);
double numericalT = getNumericalValue(changeInTime);
avgVelocity = numericalS / numericalT;
System.out.println("The Average Velocity is: " + avgVelocity);
}
如您所见,我想我可以简单地将字符与其 ascii 值进行比较。但是,它在我的双输出中包含 k 或 space,这会引发此错误。
Exception in thread "main" java.lang.NumberFormatException: For input string: "5 k"
at java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)
at java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
at java.base/java.lang.Double.parseDouble(Double.java:556)
at Main.getNumericalValue(Main.java:122)
at Main.getAverageVelocity(Main.java:393)
at Main.kineticsIn1DCalculator(Main.java:375)
at Main.performAction(Main.java:141)
at Main.runner(Main.java:29)
at Main.main(Main.java:22)
任何帮助和详尽的解释都会很棒。谢谢
你有错误,因为即使找到第一个数字,for
循环仍在继续。您只需添加 break
指令,然后 for 循环在找到的第一个数字处结束。
这是方法的最终代码getNumericalValue
:
private double getNumericalValue(String userInput) {
double numericalOutput = 0.0;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) >= 65 && userInput.charAt(i) <= 122) {
numericalOutput = Double.parseDouble(userInput.substring(0, i));
break;
}
}
return numericalOutput;
}
您只需输入该行并解析其部分。
最好引入一个class来保存一个带单位的值,其中“km north”算作一个单位。
因为 java 14 存在 record
class.
record ValueWithUnit(double value, String unit) {
public static ValueWithUnit from(String s) {
String v = s.replaceFirst("^(.*?)([ A-z].*)$", "");
String u = s.replaceFirst("^(.*?)([ A-z].*)$", "");
if (u == v) {
u = "";
}
double x = Double.parseDouble(v); // Replaces getNumericalValue(v);
return new Value(x, u);
}
@Override
public String toString() {
String.format("%f %s", value, unit);
}
}
您可以直接将其用作:
ValueWithUnit vu = new ValueWithUnit(30.0, "km");
System.out.println(vu);
代码则变为:
private void getAverageVelocity() {
// formula average velocity = displacement s / change in time t
double avgVelocity = 0.0;
System.out.println("Enter the displacement: [ex. 5 km north]");
ValueWithUnit displacement = ValueWithUnit.from(getStringInput());
System.out.println("Enter the change in time: [ex. 1 hour]");
ValueWithUnit changeInTime = ValueWithUnit.from(getStringInput());
// parse the string and change numerical input into double
double numericalS = displacement.value;
double numericalT = changeInTime.value;
avgVelocity = numericalS / numericalT;
System.out.printf("The Average Velocity is: %f %s%n", avgVelocity,
displacement.unit + "/" + changeInTime.unit);
}
你在 if 块中实际测试的是 i 处的字符是否是字母 A-Z、a-z 和其他符号(即 [ ^ ], ...etc) 检查它是否是一个数字(即 0-9)对应的十进制范围是 48-57 check this link
至于异常是因为 substring(0, 0) 会产生一个空字符串,当试图解析它时,Double.parseDouble() 会抛出异常。 这是您可以使用的解决方案:
private double getNumericalValue(String userInput) {
double numericalOutput = 0.0;
for (int i = 0; i < userInput.length(); i++) {
if (userInput.charAt(i) >= 48 && userInput.charAt(i) <= 57) {
numericalOutput = Double.parseDouble(userInput.substring(0, i + 1));
}
}
return numericalOutput;
}
注:substring(i, j) i 含,j 不含
更新: 刚刚注意到,在你的情况下发生异常是因为你试图解析字母“k”因为它通过了条件,导致 Double.parseDouble() 抛出异常。