【问题标题】:How can I efficiently (without throwing exceptions for invalid input) parse an integer in Java?如何有效地(不为无效输入抛出异常)解析 Java 中的整数?
【发布时间】:2016-01-30 06:36:48
【问题描述】:

此问题是Does java have a int.tryparse that doesn't throw an exception for bad data? 的后续问题,被标记为与Java: Good way to encapsulate Integer.parseInt() 重复。

这两个问题似乎更多地是关于如何捕获Integer.parseInt() 抛出的NumberFormatException 或通过封装Integer.parseInt() 来提供不使用异常的更好的API。

但两者都没有专门针对性能方面的问题,即如果输入不可解析为int,Java 的Integer.parseInt() 会引发异常。如果您的大部分输入由有效的ints 组成,这无关紧要。但是,如果您的输入包含大量可能是也可能不是ints 的数据并且您需要对其进行解析,那么Integer.parseInt() 将是低效的。

所以这个特定的问题是关于如何有效地解析整数,因为输入可以包含很多有效的整数,但也可以包含很多无效的整数。

【问题讨论】:

  • 如果你期望有很多不是整数的东西,多解释一下你的数据流可能会有所帮助。一种简单的方法是匹配 -?\d+ 之类的正则表达式。
  • 你可以重写parseInt。您可以使用 parseint 的 openjdk 实现作为基础,并在 int 无效时执行不引发异常的操作。这个问题stackoverflow.com/questions/299068/how-slow-are-java-exceptions 与抛出异常的表现有关
  • 我把我自己的答案放在下面。创建这个新问题的目的是解决我提到的其他两个问题没有正确解决的方面。无需重写 parseInt(),因为 Google 为我们完成了它;)
  • 我不确定我是否理解,抛出异常有什么问题?如果发生了,处理有没有什么低效的?
  • @AshwinGupta cf 我链接的问题。抛出异常非常繁重。

标签: java


【解决方案1】:

Here is a good article about efficiently parsing integers.原站挂了,所以我在回机的时候附上了链接。

返回 Integer 而不是 int 会使您的代码变慢。您可以使用文章中的代码并返回 Integer.MIN_VALUE、零或其他值,具体取决于您的场景:

public static int parseInt( final String s )
{
    if ( string == null )
        return Integer.MIN_VALUE;

    // Check for a sign.
    int num  = 0;
    int sign = -1;
    final int len  = s.length( );
    final char ch  = s.charAt( 0 );
    if ( ch == '-' )
    {
        if ( len == 1 )
            return Integer.MIN_VALUE;
        sign = 1;
    }
    else
    {
        final int d = ch - '0';
        if ( d < 0 || d > 9 )
            return Integer.MIN_VALUE;
        num = -d;
    }

    // Build the number.
    final int max = (sign == -1) ?
        -Integer.MAX_VALUE : Integer.MIN_VALUE;
    final int multmax = max / 10;
    int i = 1;
    while ( i < len )
    {
        int d = s.charAt(i++) - '0';
        if ( d < 0 || d > 9 )
            return Integer.MIN_VALUE;
        if ( num < multmax )
            return Integer.MIN_VALUE;
        num *= 10;
        if ( num < (max+d) )
            return Integer.MIN_VALUE;
        num -= d;
    }

    return sign * num;
}

【讨论】:

    【解决方案2】:

    到目前为止,在不编写我自己的整数解析代码或使用易碎正则表达式的情况下,我找到的最佳答案是使用GuavaInts.tryParse(String string)Longs.tryParse(String string, int radix) 方法。

    Longs.tryParse() 基本上是标准 Java Long.parseLong() 的重新实现,但返回 nullLong 而不是抛出 NumberFormatException。在我看来,这似乎是最好的方法:它在解析方面与Long.parseLong() 一样高效,但更有效地处理错误情况。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-08-24
      • 1970-01-01
      • 2018-02-10
      • 2013-02-13
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多