Java里String.split需要注意的用法

我们常常用String的split()方法去分割字符串,有两个地方值得注意:

1. 当分隔符是句号时("."),需要转义:

由于String.split是基于正则表达式来分割字符串,而句号在正则表达式里表示任意字符。

//Wrong:
//String[] words = tmp.split("."); //Correct:
String[] words = tmp.split("\\.");

所以,假设分隔符在正则表达式里有一定的意义时,需要格外留心,必须将它们转义才能达到分割的效果。

2. 假设字符串最后有连续多个分隔符,且这些分隔符都需要被分割的话,需要调用split(String regex,int limit)这个方法:

String abc = "a,b,c,,,";
String[] str = abc.split(","); System.out.println(Arrays.toString(str)+" "+str.length); String[] str2 = abc.split(",",-1); System.out.println(Arrays.toString(str2)+" "+str2.length);

输出如下:

[a, b, c] 3
[a, b, c, , , ] 6

需要输出csv文件的时候,尤其需要注意。

3. 假设需要快速分割字符串,split()并不是最有效的方法。在split()方法内,有如下的实现:

 public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}

频繁调用split()会不断创建Pattern这个对象,因此可以这样去实现,减少Pattern的创建:

 //create the Pattern object outside the loop
Pattern pattern = Pattern.compile(" "); for (int i = 0; i < 1000000; i++)
{
String[] split = pattern.split("Hello World", 0);
list.add(split);
}

另外split()也往往比indexOf()+subString()这个组合分割字符串要稍慢,详情可看这个帖子

我在本机做过测试,感觉indexOf()+subString()比split()快一倍:

 public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
for (int i = 100000; i < 100000 + 60; i++)
sb.append(i).append(' ');
String sample = sb.toString(); int runs = 100000;
for (int i = 0; i < 5; i++) {
{
long start = System.nanoTime();
for (int r = 0; r < runs; r++) {
StringTokenizer st = new StringTokenizer(sample);
List<String> list = new ArrayList<String>();
while (st.hasMoreTokens())
list.add(st.nextToken());
}
long time = System.nanoTime() - start;
System.out.printf("StringTokenizer took an average of %.1f us%n", time / runs
/ 1000.0);
}
{
long start = System.nanoTime();
Pattern spacePattern = Pattern.compile(" ");
for (int r = 0; r < runs; r++) {
List<String> list = Arrays.asList(spacePattern.split(sample, 0));
}
long time = System.nanoTime() - start;
System.out.printf("Pattern.split took an average of %.1f us%n", time / runs
/ 1000.0);
}
{
long start = System.nanoTime();
for (int r = 0; r < runs; r++) {
List<String> list = new ArrayList<String>();
int pos = 0, end;
while ((end = sample.indexOf(' ', pos)) >= 0) {
list.add(sample.substring(pos, end));
pos = end + 1;
}
}
long time = System.nanoTime() - start;
System.out
.printf("indexOf loop took an average of %.1f us%n", time / runs / 1000.0);
}
}
}

在jdk1.7测试后,结果如下:

StringTokenizer took an average of 7.2 us
Pattern.split took an average of 7.9 us
indexOf loop took an average of 3.5 us

------------------------------------------
StringTokenizer took an average of 6.8 us
Pattern.split took an average of 5.4 us
indexOf loop took an average of 3.1 us

------------------------------------------
StringTokenizer took an average of 6.0 us
Pattern.split took an average of 5.5 us
indexOf loop took an average of 3.1 us

------------------------------------------
StringTokenizer took an average of 5.9 us
Pattern.split took an average of 5.5 us
indexOf loop took an average of 3.1 us

------------------------------------------
StringTokenizer took an average of 6.4 us
Pattern.split took an average of 5.5 us
indexOf loop took an average of 3.2 us

本文完

上一篇:Cookie中设置了 HttpOnly,Secure 属性,有效的防止XSS攻击,X-Frame-Options 响应头避免点击劫持


下一篇:HttpURLConnection请求网络数据的GET请求