需求
将形如“1,234”、“hh1234” String类字符串转换int类型1234
常见写法
private static int getIntValue(String str) {
int r = 0;
if (str != null && str.length() != 0) {
StringBuffer bf = new StringBuffer();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c >= '0' && c <= '9') {
bf.append(c);
} else if (c == ',') {
continue;
} else {
if (bf.length() != 0) {
break;
}
}
}
try {
r = Integer.parseInt(bf.toString());
} catch (Exception e) {
}
}
return r;
}
这种做法一般应用没有问题,而且效率也可以。但有无更高效的做法呢?
高效写法
public static int string2Int(String s) {
boolean find = false;
char[] chars = s.toCharArray();
int v = 0;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c >= '0' && c <= '9') {
find = true;
v = v * 10 + c - 48;
} else {
if (find && c != ',')
break;
}
}
// System.out.println(v);
return v;
}
以上写法,使用了较少的类。几乎没有对象创建和销毁、方法调用。因而性能更高。
更高效写法
public static int string2Int2(String s) {
boolean find = false;
// char[] chars = s.toCharArray();
int v = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= '0' && c <= '9') {
find = true;
v = v * 10 + c - 48;
} else {
if (find && c != ',')
break;
}
}
// System.out.println(v);
return v;
}
注意到toCharArray方法调用也需要耗用一定时间,而且很可能涉及数组的创建。将以上写法toCharArray方法调用也省掉,性能会进一步提升。
完整代码
public class Test {
public static int string2Int(String s) {
boolean find = false;
char[] chars = s.toCharArray();
int v = 0;
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c >= '0' && c <= '9') {
find = true;
v = v * 10 + c - 48;
} else {
if (find && c != ',')
break;
}
}
// System.out.println(v);
return v;
}
public static int string2Int2(String s) {
boolean find = false;
// char[] chars = s.toCharArray();
int v = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c >= '0' && c <= '9') {
find = true;
v = v * 10 + c - 48;
} else {
if (find && c != ',')
break;
}
}
// System.out.println(v);
return v;
}
private static int getIntValue(String str) {
int r = 0;
if (str != null && str.length() != 0) {
StringBuffer bf = new StringBuffer();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (c >= '0' && c <= '9') {
bf.append(c);
} else if (c == ',') {
continue;
} else {
if (bf.length() != 0) {
break;
}
}
}
try {
r = Integer.parseInt(bf.toString());
} catch (Exception e) {
}
}
return r;
}
public static void main(String[] args) {
System.out.println(string2Int2(""));
System.out.println(string2Int2("1234"));
System.out.println(string2Int2("1,234"));
System.out.println(string2Int2("hh1234"));
System.out.println(string2Int2("hh1234gg"));
System.out.println(string2Int2("1234hh5"));
System.out.println(string2Int2("汉字1234f5"));
System.out.println(string2Int2("汉字1,234f5"));
System.out.println(getIntValue("汉字1,234f5"));
// ----------性能测试 一
// 测试 1千万次 string2Int:耗时 0.32s
long start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
string2Int("汉字1,234f5");
}
long end = System.nanoTime();
double sec = (end - start) / 1000000000.0;
System.out.println("string2Int TimeCost: " + String.valueOf(sec)
+ " second.");
// 测试 1千万次 string2Int2:耗时 0.21s
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
string2Int2("汉字1,234f5");
}
end = System.nanoTime();
sec = (end - start) / 1000000000.0;
System.out.println("string2Int2 TimeCost: " + String.valueOf(sec)
+ " second.");
// 测试 1千万次getIntValue:耗时 2.37s
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
getIntValue("汉字1,234f5");
}
end = System.nanoTime();
sec = (end - start) / 1000000000.0;
System.out.println("getIntValue TimeCost: " + String.valueOf(sec)
+ " second.");
// ----------性能测试 二
// 测试 1千万次 string2Int:耗时 0.12s
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
string2Int2("1234");
}
end = System.nanoTime();
sec = (end - start) / 1000000000.0;
System.out.println("string2Int 1234 TimeCost: " + String.valueOf(sec)
+ " second.");
// 测试 1千万次 Integer.valueOf:耗时 0.43s
start = System.nanoTime();
for (int i = 0; i < 10000000; i++) {
Integer.valueOf("1234").intValue();
}
end = System.nanoTime();
sec = (end - start) / 1000000000.0;
System.out.println("Integer.valueOf 1234 TimeCost: "
+ String.valueOf(sec) + " second.");
}
}
总结
- 一千万次调用,高效写法要比常见写法性能高10倍。
- 使用基础类型要比使用类 性能上要高的多。
- v = v * 10 + c - 48; 这种编程技巧可以减少循环,进而提升性能。