检查逗号分隔字符串是否包含至少1个有效整数的最快方法?

时间:2015-09-30 20:34:22

标签: java string performance

我有一个逗号分隔正整数的字符串,例如:

1,34,433,12

确定字符串是否包含至少1个整数的最快方法是什么?

现在我split(",")循环生成String[]并尝试将每个元素解析为int。

这样可以获得String的List<Integer>,但我希望以最快的方式确定String是否对此有效。

1a,2b,13是可以接受的。 1a,2b,13c是不可接受的。

4 个答案:

答案 0 :(得分:3)

尝试:

public static boolean containsInt(String string) {
    boolean onlyDigits = true;
    boolean atLeastOneDigit = false;
    int len = string.length();
    for (int i = 0; i < len; i++) {
        char c = string.charAt(i);
        if (c == ',') {
            if (atLeastOneDigit && onlyDigits) {
                return true;
            }
            onlyDigits = true;
            atLeastOneDigit = false;
            continue;
        }
        boolean isDigit = c >= '0' && c <= '9';
        onlyDigits &= isDigit;
        atLeastOneDigit |= isDigit;
    }
    return atLeastOneDigit && onlyDigits;
}

现在,使用Guava的更易读的版本:

public static boolean containsInt(String text) {
    for (String s : Splitter.on(',').split(text) {
        if (Ints.tryParse(s) != null)
            return true;
    }
    return false;
}

答案 1 :(得分:2)

我测试了Jim(OP),Jean和Andreas提出的解决方案(仅在循环中编译模式一次)。

Source code测试。我用了jmh

结果

Benchmark                 Mode  Cnt     Score    Error  Units
MyBenchmark.testJim      thrpt   20    32.895 ±  0.708  ops/s
MyBenchmark.testJean     thrpt   20  2806.981 ± 31.295  ops/s
MyBenchmark.testAndreas  thrpt   20    41.789 ±  6.033  ops/s

Jean的解决方案绝对是最快的。在Java中我无法想到更快的东西。

答案 2 :(得分:0)

由于你的String只需要包含至少一个数字,为​​什么不迭代它并检查是否至少有一个数字(0-9),以及那里是否有任何非数字/逗号符号? / p>

答案 3 :(得分:0)

这是正则表达式的工作。

当你看到.toCharArray()某人重新发明正则表达式时,大约有90%的时间。不要重新发明轮子!

public class Jim {
  public static void main(String... args) {
    final String[] strings = new String[]{
        //valid
        "1,34,433,12",
        "12,safdg,sfdg",
        "asfd,asdf,12",
        "asfd,10,jrtj",
        "12356",
        ",12356,",
        //invalid
        "asdf",
        "1a,2b,13c",
        ",asdf,",
        ",,,",
        "",
    };
    for (String s : strings) {
      System.out.println(String.format("data: [%s], outcome: [%s]", s, hasNumericField(s)));
    }
  }

  //\A matches the start of the input, thus
  //(\A|,) matches the start of the input or a comma, thus 
  //(\z|,) works the same way but with the end of the input.
  //\d+ matches one or more digits.
  private static final Pattern pat = Pattern.compile("(\\A|,)\\d+(\\z|,)");

  private static boolean hasNumericField(final String commaSeparatedData) {
    return pat.matcher(commaSeparatedData).find();
  }

}

正则表达式的一个乐趣是它能很好地适应输入的变化。你只需改变表达式。如果你手工编写一些你可能需要重做的东西 - &gt;测试 - &gt;如果输入改变,则调试它。