【问题标题】:Determine if a String is an Integer in Java [duplicate]确定字符串是否是Java中的整数[重复]
【发布时间】:2011-07-23 07:26:46
【问题描述】:

我正在尝试确定字符串数组中的特定项目是否为整数。

我在.split(" ")'ing String 形式的中缀表达式,然后尝试将结果数组拆分为两个数组;一个用于整数,一个用于运算符,同时丢弃括号和其他杂项。实现这一目标的最佳方法是什么?

我以为我可以找到Integer.isInteger(String arg) 方法之类的,但没有这样的运气。

【问题讨论】:

  • 我不明白有几个 java 更新,这样简单的帮助方法没有内置到工具包中。
  • @tony9099 这是一种边缘情况,从我所看到的斜线来看,这个问题仍然有很多观点,相当独特。接受的解决方法(我接受作为答案)可能比使其成为 Java 标准更好。
  • @Nick 进一步证明您不必使用 Java,尽管有三个有用的解决方案(诚然,每个都比前一个)。我认为这是一个明确的指标,这是一种极端情况,在大多数情况下,您最好改变解决问题的方式,这样您就不需要我的解决方案,而是实际使用它。

标签: java string int


【解决方案1】:

作为尝试解析字符串并捕获NumberFormatException 的替代方法,您可以使用正则表达式;例如

if (Pattern.compile("-?[0-9]+").matches(str)) {
    // its an integer
}

这可能会更快,尤其是在您预编译和重用正则表达式的情况下。

但是,这种方法的问题是,如果str 表示的数字超出合法的int 值范围,Integer.parseInt(str) 也会失败。虽然可以制作一个只匹配Integer.MIN_INTInteger.MAX_INT 范围内的整数的正则表达式,但这并不是一个漂亮的景象。 (而且我不会尝试...)

另一方面......出于验证目的,分别处理“不是整数”和“整数太大”可能是可以接受的。

【讨论】:

    【解决方案2】:

    使用正则表达式更好。

    str.matches("-?\\d+");
    
    
    -?     --> negative sign, could have none or one
    \\d+   --> one or more digits
    

    这里用NumberFormatException不好,如果可以改用if-statement


    如果你不想要前导零,你可以使用正则表达式如下:

    str.matches("-?(0|[1-9]\\d*)");
    

    【讨论】:

    • 另外......如果有人想处理信号“+”,我制作了那个版本(关于你的):str.matches("^[+-]?\\d+$")
    • 很好奇为什么这不是选择的答案...
    • @BrentHronik 这是一个非常干净的单线,但根据stackoverflow.com/questions/237159/… 的答案之一,它比 corsiKa 建议的方法慢 10 倍。
    • 在初始化过程中,检查配置输入字符串的值,性能不是问题+1
    • 正则表达式中的前导 ^ 和尾随 $ 是多余的,因为 String.matches() 总是匹配整个字符串。
    【解决方案3】:
    public boolean isInt(String str){
        return (str.lastIndexOf("-") == 0 && !str.equals("-0")) ? str.substring(1).matches(
                "\\d+") : str.matches("\\d+");
    }
    

    【讨论】:

    • 这对于字符串 ---0--- 也将返回 true,它肯定不是 int。
    • @Matthias 你说得对,我还没有测试过,我现在编辑了我的答案来检查它
    【解决方案4】:

    最简单的方法是遍历字符串并确保所有元素都是给定基数的有效数字。这是尽可能高效的方法,因为您必须至少查看每个元素一次。我想我们可以根据基数对其进行微优化,但出于所有意图和目的,这与您期望的一样好。

    public static boolean isInteger(String s) {
        return isInteger(s,10);
    }
    
    public static boolean isInteger(String s, int radix) {
        if(s.isEmpty()) return false;
        for(int i = 0; i < s.length(); i++) {
            if(i == 0 && s.charAt(i) == '-') {
                if(s.length() == 1) return false;
                else continue;
            }
            if(Character.digit(s.charAt(i),radix) < 0) return false;
        }
        return true;
    }
    

    或者,您可以依靠 Java 库来实现这一点。它不是基于异常的,并且会捕获您能想到的几乎所有错误情况。它会贵一点(你必须创建一个 Scanner 对象,在一个非常紧密的循环中你不想这样做。但它通常不应该太贵,所以对于日常操作应该是相当可靠的。

    public static boolean isInteger(String s, int radix) {
        Scanner sc = new Scanner(s.trim());
        if(!sc.hasNextInt(radix)) return false;
        // we know it starts with a valid int, now make sure
        // there's nothing left!
        sc.nextInt(radix);
        return !sc.hasNext();
    }
    

    如果最佳实践对您来说并不重要,或者您想欺骗负责您的代码审查的人,请试试这个:

    public static boolean isInteger(String s) {
        try { 
            Integer.parseInt(s); 
        } catch(NumberFormatException e) { 
            return false; 
        } catch(NullPointerException e) {
            return false;
        }
        // only got here if we didn't return false
        return true;
    }
    

    【讨论】:

    • “非异常方法”会将“-”视为整数。
    • 这当然是一种非正统的做法。作为一般规则,您希望避免使用异常来指示执行流程。或者正如 Joshua Bloch 在他的“Effective Java item 57: Use exceptions only for exception conditions”中所说的那样。他对使用异常迭代数组的评论实际上是// Horrible abuse of exceptions. Don't ever do this!
    • 有人可以向我解释为什么第三种方法是不好的做法吗?因为基于异常的执行流程?
    • 它们被称为“例外”是有原因的。在一个完美的世界里,你永远不会例外。假设我的老板要求我完成一项任务。他会期待我说“是的,先生!”但我可能会回答“我现在有很多事情要做,如果不让现有工作失败,我不能接受新任务。”他已经为这两种情况做好了准备。他不准备让我打他的脸。我丢了工作,他叫保安。现在想象一下,如果他为我打电话给保安,只是说我有太多工作 - 那是第三种方法:打电话给警察做一些应该预料到的事情。
    • 使用非异常方法,字符串“9999999999999999999999”是一个有效整数
    【解决方案5】:

    或者您可以向 Apache Commons 的好朋友寻求一点帮助:StringUtils.isNumeric(String str)

    【讨论】:

    • 我对这种方法的唯一疑问是 "" 返回真。我们的直觉告诉我们空字符串不是一个数字(OP 问题的整数),您可以对其执行数学运算,但我想您可以说您不能证明空字符串是非数字的,因为我们没有告诉您然而字符串会是什么。
    • 我希望这对我来说是一个很好的答案,但不仅“”返回真,而且“-1”也会返回假。这意味着它既不会为所有有效整数返回 true,也不会返回 true 的事实保证将其传递给 Integer.parseInt 不会引发异常。
    • @jhericks 感谢您指出这一点。几年前我第一次回答这个问题时,它引用的是旧版本的 Commons StringUtils。他们已经更新了 api,现在空字符串被认为是非数字的。不幸的是,负面情况必须单独处理,这是一个缺点,但解决方法是微不足道的。只需检查 numberCandidate.startsWith("-") 和在 parseInt 调用之后带有否定的子字符串调用,假设值当然是数字。
    • StringUtils.isNumeric(String) 不仅没有满足最初检查字符串“是否为整数”的请求,而且还建议使用像 apache commons 这样的野兽以避免编写单行代码恕我直言,这不是理性的。
    • 不惜一切代价避免使用 Apache“公地”。虽然有时乍一看是个好主意,但它只是一堆反模式,会给你带来依赖地狱,导致有争议的结果。
    【解决方案6】:

    或者干脆

    mystring.matches("\\d+")

    尽管对于大于 int 的数字它会返回 true

    【讨论】:

    • 不起作用。匹配任何连续包含 1 个或多个数字的字符串。例如,blabla. 0 bla bla bla 匹配。
    • @njzk2 使用 "^-?\\d+$" 作为你的正则表达式
    • 值 x 和 x > Integer.MaxValue 怎么样,最小值相同?
    • njzk2 - 它确实有效,因为 String.matches() 仅在整个字符串与模式匹配时才返回 true,尽管您必须遵循从 String.matches() 到 Pattern.matches() 的文档跟踪到Matcher.matches() 来发现这个事实。
    • 适用于小于 Integer.MaxValue 的数字。这个解决方案虽然表现不佳。在此处查看基准:baeldung.com/java-check-string-number
    【解决方案7】:

    如果字符串不是有效整数,您可以使用Integer.parseInt(str) 并捕获NumberFormatException,方式如下(所有答案都指出):

    static boolean isInt(String s)
    {
     try
      { int i = Integer.parseInt(s); return true; }
    
     catch(NumberFormatException er)
      { return false; }
    }
    

    但是,请注意,如果计算的整数溢出,将抛出相同的异常。你的目的是找出它是否是一个有效的整数。因此,制作自己的方法来检查有效性会更安全:

    static boolean isInt(String s)  // assuming integer is in decimal number system
    {
     for(int a=0;a<s.length();a++)
     {
        if(a==0 && s.charAt(a) == '-') continue;
        if( !Character.isDigit(s.charAt(a)) ) return false;
     }
     return true;
    }
    

    【讨论】:

      【解决方案8】:

      您可以使用Integer.parseInt()Integer.valueOf() 从字符串中获取整数,如果它不是可解析的int,则捕获异常。你要确保抓住它可以抛出的NumberFormatException

      注意 valueOf() 将返回一个 Integer 对象,而不是原始 int 可能会有所帮助。

      【讨论】:

      • 为清晰起见进行了编辑。不需要厚脸皮。
      • @krmby 的目的不是实际检索该值,而只是确定它是否符合格式。在这方面,Chad 是正确的,因为这两种方法都可以正常工作。
      • @glowcoder 你在谈论我不是答案的编辑版本。我现在两种方法都可以正常工作,但这并没有改变Integer.parseInt() 的返回类型是int 的事实。
      • @krmby 一个有趣的观点。我专注于第一段(在我回顾时,它保持不变。)
      • @glowcoder 此答案的作者说:请注意,这些方法将返回一个整数对象,而不是原始 int,这可能会有所帮助。我parseInt() 返回int。我对第一段说了NOTHING。根据我的评论,Chad La Guardia 更正他的回答,一切都很好。所以我实际上并没有明白你的意思。
      【解决方案9】:

      您想使用Integer.parseInt(String) 方法。

      try{
        int num = Integer.parseInt(str);
        // is an integer!
      } catch (NumberFormatException e) {
        // not an integer!
      }
      

      【讨论】:

      • 为什么评价不高?这对我来说似乎是最简单的,还是我遗漏了一些缺点?
      • @bobismijnnaam 这样做的问题是,它会产生一个相对昂贵的异常,并且你有一些讨厌的嵌套,这可能会影响可读性。
      • 异常表示出现问题,这种用法肯定是对这个设计原则的滥用。仅使用 Integer.parserInt() after 您确保 String 确实包含整数值。如果这样做并且 Integer.parseInt 仍然抛出异常,那么您知道您的代码中有问题需要修复(或者,为了完整起见, Integer.parseInt 本身有问题,但这个选项不太可能)
      • 无效,将 aaaa 转换为某个值
      猜你喜欢
      • 1970-01-01
      • 2016-02-18
      • 2011-08-08
      • 1970-01-01
      • 1970-01-01
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多