如何删除非数字?

Mil*_*lli 4 java

private String removeNonDigits(final String value) {         
   if(value == null || value.isEmpty()){
        return "";
   }
   return value.replaceAll("[^0-9]+", "");
}
Run Code Online (Sandbox Code Playgroud)

有更好的方法吗?Apache的StringUtils有类似的方法吗?

fin*_*nnw 8

为了好玩,我跑了一个基准:

import java.util.List;
import java.util.regex.Pattern;

import com.google.common.base.Joiner;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.primitives.Chars;

public final class Main {
    private static final String INPUT = "0a1b2c3d4e";
    private static final int REPS = 10000000;

    public static volatile String out;

    public static void main(String[] args) {
        System.err.println(removeNonDigits1(INPUT));
        System.err.println(removeNonDigits2(INPUT));
        System.err.println(removeNonDigits3(INPUT));
        System.err.println(removeNonDigits4(INPUT));
        System.err.println(removeNonDigits5(INPUT));

        long t0 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits1(INPUT);
        }
        long t1 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits2(INPUT);
        }
        long t2 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits3(INPUT);
        }
        long t3 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits4(INPUT);
        }
        long t4 = System.currentTimeMillis();
        for (int i = 0; i < REPS; ++ i) {
            out = removeNonDigits5(INPUT);
        }
        long t5 = System.currentTimeMillis();
        System.err.printf("removeNonDigits1: %d\n", t1-t0);
        System.err.printf("removeNonDigits2: %d\n", t2-t1);
        System.err.printf("removeNonDigits3: %d\n", t3-t2);
        System.err.printf("removeNonDigits4: %d\n", t4-t3);
        System.err.printf("removeNonDigits5: %d\n", t5-t4);
    }

    private static final String PATTERN_SOURCE = "[^0-9]+";
    private static final Pattern PATTERN = Pattern.compile(PATTERN_SOURCE);

    public static String removeNonDigits1(String input) {
        return input.replaceAll(PATTERN_SOURCE, "");
    }

    public static String removeNonDigits2(String input) {
        return PATTERN.matcher(input).replaceAll("");
    }

    public static String removeNonDigits3(String input) {
        char[] arr = input.toCharArray();
        int j = 0;
        for (int i = 0; i < arr.length; ++ i) {
            if (Character.isDigit(arr[i])) {
                arr[j++] = arr[i];
            }
        }
        return new String(arr, 0, j);
    }

    public static String removeNonDigits4(String input) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < input.length(); ++ i) {
            char c = input.charAt(i);
            if (Character.isDigit(c)) {
                result.append(c);
            }
        }
        return result.toString();
    }

    public static String removeNonDigits5(String input) {
        List<Character> charList = Chars.asList(input.toCharArray());
        Predicate<Character> isDigit =
            new Predicate<Character>() {
                public boolean apply(Character input) {
                    return Character.isDigit(input);
                }
            };
        Iterable<Character> filteredList =
            Iterables.filter(charList, isDigit);
        return Joiner.on("").join(filteredList);
    }
}
Run Code Online (Sandbox Code Playgroud)

得到了这些结果:

removeNonDigits1: 74656
removeNonDigits2: 52235
removeNonDigits3: 4468
removeNonDigits4: 5250
removeNonDigits5: 29610
Run Code Online (Sandbox Code Playgroud)

有趣的部分是removeNonDigits5(Google Collections版本)应该是一个愚蠢,过于复杂和无效的解决方案的例子,但它的速度是正则表达式版本的两倍.

更新:预编译正则表达式可以提高速度,但不会像人们预期的那样多.

重新使用它Matcher会带来另一个轻微的加速,但可能不值得牺牲线程安全性.

  • 在运行基准测试时,必须让VM"热身"或者代码可能永远不会被编译.规则是做几个试验,每个试验由N次迭代组成,选择N使得你的试验持续一秒钟.每次试用后,将实际时间除以迭代计数报告给控制台.然后观察直到结果稳定 - 他们应该得到_very_稳定.然后再次运行它,看看你如何获得完全不同的稳定结果!在对ImmutableSet进行基准测试时,我的习惯是每次运行7次基准测试(7次单独的VM调用)并取中位数. (2认同)

And*_*yle 7

你的方法对我来说似乎很好 - 当你说"更好"时,你正在寻找什么?您的方法在实现中是清晰易懂的,并且具有相当好的性能.

特别是,除非您的应用程序包含在紧密循环中不断调用此方法,否则我认为您不会因为尝试使其更高效而获得任何明显的效果.不要过早优化; 首先介绍并优化热点.