【问题标题】:Converting String to Integers the safe way将字符串转换为整数的安全方式
【发布时间】:2013-05-30 06:29:16
【问题描述】:

我有一个小方法可以将字符串转换为整数。由于字符串是方法的参数,我想确保该字符串是可转换的。所以我只是想知道什么是最安全和/或最快的方法。


版本 A:保持原样并承担风险(我试图避免)

public static int stringToInt(String param) {
        return Integer.valueOf(param);
}

(在速度方面,B、C版会有什么不同?)


版本 B:捕获异常

public static int stringToInt(String param) {
        try {
                return Integer.valueOf(param);
        } catch(NumberFormatException e) {
                return -1;
        }
}

版本C:检查字符串的每个字母,看看它是否是数字数字

public static int stringToInt(String param) {
        for(char c : param.toCharArray()) {
                if(!Character.isDigit(c))
                        return -1;
        }
        return Integer.valueOf(param);
}

请注意,参数必须是正数,-1 应该是我的小程序中的“错误值”,换句话说,所有三个版本的方法都可以在我的程序中完美运行。

我非常愿意接受您可以给我的任何其他建议,因此,如果您认为自己的版本更好,请随时创建您自己的版本。

非常感谢您提前支持。

【问题讨论】:

  • 如果错误不是正确的行为,并且如果您不想在更改的更高位置捕获NumberFormatException,则第一个版本只有“风险”。抛出异常可能是对错误输入的完美反应。
  • 在我看来,第一个是最快的,但是如果你输入一个非数字值它会抛出异常。第二个对我来说是最好的,因为它有一个 catch 来防止异常停止你的程序。最后一个,它只是第二个的长版本。
  • 版本 C 在负整数上失败
  • @bengoesboom 我提到输入必须是正数
  • C 正在检查 A 和 B 是否已经在内部进行。 B 是安全和速度之间的一个很好的折衷方案。

标签: java type-conversion


【解决方案1】:

Guava 为此提供了一个实用方法,如果您的字符串无法解析,则返回 null。

https://google.github.io/guava/releases/19.0/api/docs/com/google/common/primitives/Ints.html#tryParse(java.lang.String)

Integer result = Ints.tryParse("1");  //returns 1
Integer result = Ints.tryParse("-1"); //returns -1
Integer result = Ints.tryParse("a");  //returns null

【讨论】:

  • 注意:如果字符串为空,Ints.tryParse(String string) 将抛出 NullPointerException。
【解决方案2】:

首先,请注意C 版本不是防弹的:它会拒绝负数,并且不会捕获太大的数字。

版本B 没问题,但它使调用者改变了编码风格:调用者需要一直检查-1,而不是捕获错误并将其与其他错误一起处理。在您读取多个整数的情况下,这可能不是最理想的,但错误处理并不取决于哪个特定的整数失败。此外,使用您的 API 的新编码人员可能会忘记检查 -1,并无意中使用了错误代码。

这就是为什么我会保留第一个选项:使用版本 A 的代码对于任何了解 Java API 的人来说都会立即熟悉,而无需了解函数内部发生了什么。

【讨论】:

  • OP 指出他们的实际方法做了“其他事情”。它可能不那么方便地命名为stringToInt。明确声明抛出的异常可能是个好主意,除非方法名称真的像 stringToInt 一样清晰(当然还有 javadoc 与上述所有内容一起使用)
【解决方案3】:

我相信修改后的 B 抛出异常而不是返回 -1 将是最佳选择。最好将异常抛出到某个级别,以便对其进行处理以向用户发送正确的响应。返回像 -1 这样的值会使您的代码容易出错。假设另一个程序员正在使用您的方法,并且他/她只有您的方法的签名。因此,从签名中不清楚他/她应该编写什么代码来处理异常或错误场景。但是,如果您抛出异常并将其添加到您的方法声明中,那么它将使其他程序员能够正确使用您的方法以及所需的异常处理。对我来说,这看起来是最好的:

public static int stringToInt(String param) throws NumberFormatException {
        try {
                return Integer.valueOf(param);
        } catch(NumberFormatException e) {
               // return -1;
               throw e;
        }
}

【讨论】:

  • 为什么要捕获异常?
【解决方案4】:

没有任何 API 的 Java 8:

 Optional.ofNullable(strNum)
         .map(Integer::valueOf).orElse(null);

【讨论】:

  • 如果数字以空格开头,则会出现错误:线程“main”中的异常 java.lang.NumberFormatException:对于输入字符串:“1”
【解决方案5】:
public int stringToInt(String param) throws NumberFormatException {

    Optional.ofNullable(param.replaceAll("\\s+", ""))
         .map(Integer::valueOf).orElse(null);

/*
                      or

    Optional.ofNullable(param.replaceAll(" ", ""))
         .map(Integer::valueOf).orElse(null);

*/

}

使用 replaceAll 替换空格,加号对 cpu 友好,即使看起来不需要。

【讨论】:

    【解决方案6】:

    我使用了 2 个答案的组合来确保 null、空字符串或空白字符串以及非数字字符的安全:

    public static Integer safeStringToInt(String param) {
        return Optional.ofNullable(param).map(Ints::tryParse).orElse(null);
    }
    

    【讨论】:

      猜你喜欢
      • 2010-12-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-30
      • 2023-03-10
      • 2014-04-03
      相关资源
      最近更新 更多