目录
java的分割方式:
1.string.split
这是在使用java时,最常用的分割字符串的方法,非常好用,比如
按符号进行分割
// 分割逗号
String str = "a,b,c,d";
String[] strs = str.split(",");
// 分割#号
String str = "a#b#c#d";
String[] strs = str.split("#");
甚至是多字符分割
// 分割#号
String str = "a#$b#$c#$d";
String[] strs = str.split("#$");
但是,split的分割,是按正则的方式进行匹配的,字符串短的话,倒是无所谓,一但字符串比较长,而且需要大批量分割,比如
List<String> list = new ArrayList<String>();
for (int i = 0; i < 100000; i++) {
String str = i + "#a" + i + "#b"+i ........................; // 省略长度
list.add(str);
}
// 年轻人,耗子尾汁
for (String str : list) {
String[] strs = str.split("#");
// 其他代码
}
类似这种,数据量大的,不出意外的话,会out of memory。可能你想说老子TM内存32G,跑起进程粑粑C。加大内存就完事,那下面就不用看了。
那么大批量的长字符串分割,得怎么搞咧?
实际上,有其他方式,比如 StringTokenizer
2.StringTokenizer
这是个好东西,用它来进行字符串的分割,是挺不错的,但是它处理的方式,没有split来的方便,比如:
String line = "a#b#c#d";
StringTokenizer strToke = new StringTokenizer(line, "#");
while(strToke.hasMoreTokens()){
// 建议先取出来,因为每调一次strToke.nextToken(),就走一个
String val = strToke.nextToken();
String vals = strToke.nextToken(); // 不要这么玩,val 和 vals 将不一样
}
它有个麻烦的一点。这个可以看源码或测试发现,它会跳过空字符的部分,比如
String line = "a##b#c#d";
StringTokenizer strToke = new StringTokenizer(line, "#");
while(strToke.hasMoreTokens()){
String val = strToke.nextToken();
}
// 以上如果按照split的结果,会是
a
b
c
d
// 但StringTokenizer的结果,会是
a
b
c
d
// 或许那个空格,正是你需要保留的,但是StringTokenizer它没有给你留下来
而且,取值相对不方便,比如,你需要这样:
StringTokenizer strToke = new StringTokenizer(line, "#");
int i = 0;
while(strToke.hasMoreTokens()){
String val = strToke.nextToken();
switch (i) {
case 1:
type = val;
break;
case 2:
value = val;
break;
default:
break;
}
i++;
}
再一点是,StringTokenizer 没办法进行多字符分割,比如你想进行"#$"的分割,然而,它找到#就返回了。
所以说世界上所有好的玩意,都有一些不如意。
3.StringUtils的split 相关方法
common包的工具类StringUtils确实提供了String.split 类似的方法,返回的结果也跟String.split 一样,都可以用数组进行接收。但是,它也跟StringTokenizer 一样,无法进行多字符的分割。但是,这些分割效率比较高的,稍微瞅瞅源码,会发现,他们是ChatAt 分开字符串,进行匹配的。
4.如何解决循环中耗内存的长字符串的分割
如果你的业务类型,只需要 单字符 分割的,StringUtils的split方法,已经足够了。但如果你需要进行多字符串 分割,老老实实自己写一个吧,也不难,通过CharAt的方式就行了。