java中在处理String字符串时,很多场合都要使用split方法
本文就全面剖析 split(String regex, int limit)的用法
先来看看API:
/ **
* @param regex
* the delimiting regular expression
*
* @param limit
* the result threshold, as described above
*
* @return the array of strings computed by splitting this string
* around matches of the given regular expression
*
* @throws PatternSyntaxException
* if the regular expression's syntax is invalid
*
* @see java.util.regex.Pattern
*
* @since 1.4
* @spec JSR-51
*/
public String[] split(String regex, int limit) {
return Pattern.compile(regex).split(this, limit);
}
经过上面一篇的内容,已经知道了第一个参数是正则表达式
这里就着重说下第二个参数的含义,就是返回值数组的最大长度
来个例子
Code:
package chapter4;
/**
* Created by MyWorld on 2016/3/28.
*/
public class StringSplitDemo {
public static void main(String[] args) {
String demoStr = "v1|v2|v3";
String[] result = demoStr.split("\\|", 2);
for (String s : result) {
System.out.println(s);
}
}
}
执行下看看是不是返回数组的长度 是不是最大是2
Output:
v1
v2|v3
没有看懂吧
一起再来看看API
聊聊个人的理解,使用limit值,可以提高效率
就以刚才的例子,因为是split后的数组长度是3,如果limit是2,则就少匹配一次了
不少tx是不是觉得split(String regex, int limit)方法中的代码看着有些眼熟
是的,就是正则表达式30分钟入门系列里使用java.utilPattern
看下这个API的源码
public String[] split(CharSequence input, int limit) {
int index = 0;
boolean matchLimited = limit > 0;
ArrayList matchList = new ArrayList();
Matcher m = matcher(input);
// Add segments before each match found
while(m.find()) {
if (!matchLimited || matchList.size() < limit - 1) {
String match =
input.subSequence
(index,
m.start()
).toString();
matchList.add(match);
index = m.end();
} else if (matchList.size() == limit - 1) { // last one
String match = input.subSequence(index, input.length()).toString();
matchList.add(match);
index = m.end();
}
}
// If no match was found, return this
if (index == 0)
return new String[] {input.toString()};
// Add remaining segment
if (!matchLimited || matchList.size() < limit)
matchList.add(input.subSequence(index, input.length()).toString());
// Construct result
int resultSize = matchList.size();
if (limit == 0)
while (resultSize > 0 && matchList.get(resultSize-1).equals(""))
resultSize--;
String[] result = new String[resultSize];
return
matchList.subList(0, resultSize).toArray
(result);
}
上述源码也印证刚才的分析。
如果确定只获取前几个split后的子串,使用合适的limit值会减少使用正则表达式匹配的次数,有利于提高效率
如果对多个字符串进行split操作,直接使用字符串的split(String regex)是否合适呢?
当然在功能上是没有影响,这个地方聊聊性能吧
大家看看下面下面这两种写法的效率
Code:
package chapter4;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
/**
* Created by MyWorld on 2016/3/28.
*/
public class StringSplitDemo {
public static void main(String[] args) {
List source = new ArrayList(10000);
String demoStr = "v1|v2|v3";
for (int i = 0; i < 10000; i++) {
source.add(demoStr);
} long begin = System.currentTimeMillis();
for (String str : source) {
str.split("\\|");
}
System.out.println("Cost :" + (System.currentTimeMillis() - begin));
begin = System.currentTimeMillis();
Pattern pattern = Pattern.compile("\\|");
for (String str : source) {
pattern.split(str);
}
System.out.println("Cost :" + (System.currentTimeMillis() - begin));
}
}
执行下看看结果
Output:
Cost :53
Cost :14
从上面的执行结果上看,差别不是很大
因为上面使用正则表达式也比较简单了
使用相同正则表达式匹配多个字符串的场景,建议直接使用
java.util.regex.Pattern
而不是使用字符串的split方法
如果数据量不大,差别就不明显,根据情况斟酌使用吧