private String removeNonDigits(final String value) {
if(value == null || value.isEmpty()){
return "";
}
return value.replaceAll("[^0-9]+", "");
}
有更好的方法吗? Apache的StringUtils是否有类似的方法?
答案 0 :(得分: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);
}
}
得到了这些结果:
removeNonDigits1: 74656
removeNonDigits2: 52235
removeNonDigits3: 4468
removeNonDigits4: 5250
removeNonDigits5: 29610
有趣的部分是removeNonDigits5
(Google Collections版本)应该是一个愚蠢,过于复杂和无效的解决方案的例子,但它的速度是正则表达式版本的两倍。
<强>更新强>: 预编译正则表达式可以提高速度,但不会像人们预期的那样多。
重新使用Matcher
会带来另一个轻微的加速,但可能不值得牺牲线程安全性。
答案 1 :(得分:7)
你的方法对我来说似乎很好 - 当你说“更好”时,你正在寻找什么?您的方法在实现中是清晰易懂的,并且具有相当好的性能。
特别是,除非您的应用程序包含在紧密循环中不断调用此方法,否则我认为您不会因为尝试使其更高效而获得任何明显的效果。不要过早优化;首先介绍并优化热点。
答案 2 :(得分:3)
如果这是一个经常被调用的方法,那么可能从编译正则表达式到模式并从每次重用它时获得加速:
private static final Pattern digits = Pattern.compile("[^0-9]"); private String removeNonDigits(final String value) { if(value == null || value.isEmpty()){ return ""; } return digits.matcher(value).replaceAll(""); }
答案 3 :(得分:1)
另一个版本可能是:
public static String removeNonDigits(final String value) {
if (value == null || value.isEmpty()) {
return "";
}
StringBuilder sb = new StringBuilder(value.length());
for (int i = 0; i < value.length(); i++) {
char c = value.charAt(i);
if (Character.isDigit(c))
sb.append(c);
}
return sb.toString();
}
答案 4 :(得分:0)
public static String getOnlyNumerics(String str)
{
if (str == null)
{
return null;
}
StringBuffer strBuff = new StringBuffer();
char c;
for (int i = 0; i < str.length() ; i++)
{
c = str.charAt(i);
if (Character.isDigit(c))
{
strBuff.append(c);
}
}
return strBuff.toString();
}
答案 5 :(得分:0)
只有一个建议: 值。的修剪()强> .isEmpty() 要么 (0 ==值。的修剪()强>。长度())
如果你有
String value=" ";
没有方法trim()
value == null || value.isEmpty()== false
方法trim()
value == null || value.isEmpty()== true
第二个在功能上更正确恕我直言
答案 6 :(得分:0)
将我的变种4版本添加到 finnw 上面的乐趣:
public static String removeNonDigits4a(String input) {
char[] chars = input.toCharArray();
int l = chars.length;
int m = 0;
char c;
for (int n = 0; n < l; ) {
if (Character.isDigit(c = chars[n++])) {
chars[m++] = c;
}
}
return new String(chars, 0, m);
}