google的guava库是个很不错的工具库,这次来学习其spliiter的用法,它是一个专门用来
分隔字符串的工具类,其中有四种用法,分别来小结
1 基本用法
- import com.google.common.base.Splitter;
- public class GuavaSplitterExample {
- public static void main(String[] args) {
- String str = "a,,b, c,,,d";
- Iterable<String> result = Splitter.on(',')
- .split(str);
- System.out.println("--start--");
- for(String s: result){
- System.out.println(s);
- }
- System.out.println("--end--");
- }
- }
输出:
–start–
a
b
c
d
–end–
2) 去除空格,使用omitEmptyStrings
- String str = "a,,b, c,,,d";
- rable<String> result = Splitter.on(',')
- .omitEmptyStrings()
- .split(str);
输出:
–start–
a
b
c
d
–end–
3) 去除每一行的空格
- String str = "a,,b, c,,,d";
- erable<String> result = Splitter.on(',')
- .trimResults()
- .omitEmptyStrings()
- .split(str);
输出:
–start–
a
b
c
d
–end–
4) 还可以指定使用哪些字符去除
- String str = "a,,b,c1,,,d2";
- Iterable<String> result = Splitter.on(',')
- .trimResults(CharMatcher.DIGIT)
- .omitEmptyStrings()
- .split(str);
输出:
–start–
a
b
c
d
–end–
===================================================
性能对比:
首先看基本的使用方法:
- // Apache StringUtils...
- String[] tokens1= StringUtils.split("one,two,three",',');
- // Google Guava splitter...
- Iteratable<String> tokens2 = Splitter.on(','),split("one,two,three");
很明显,google提供的方法更加的面向对象一点,因为它要先创建一个Splitter对象,然后使用它来分割字符串,而apache的方法则有点函数式编程的味道,它的方法都是静态的。
这里我更加倾向于采用google的splitter,因为这个对象是可以重用的,且可以在其上附加更多的功能,比如trim,去掉空的元素等,一切都很简单。
- Splitter niceCommaSplitter = Splitter.on(',') .omitEmptyString().trimResults();
- niceCommaSplitter.split("one,, two, three"); //"one","two","three"
- niceCommaSplitter.split(" four , five "); //"four","five"
看起来有点用,还有其他区别么?
另外一个需要注意的地方就是Splitter返回的是Iteratable<String>,而StringUtils.split返回的是一个String数组。
大部分使用分隔符的情况是我们需要对字符串按照分隔符进行遍历处理,仅此而已。
下面就是常用的代码性能对比的例子:
- final String numberList = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";
- long start = System.currentTimeMillis();
- for(int i=0; i<1000000; i++) {
- StringUtils.split(numberList , ',');
- }
- System.out.println(System.currentTimeMillis() - start);
- start = System.currentTimeMillis();
- for(int i=0; i<1000000; i++) {
- Splitter.on(',').split(numberList );
- }
- System.out.println(System.currentTimeMillis() - start);
代码很简单,就是都对同一个字符串进行100万次的分隔操作,看看时间上的区别,结果如下:
- 983
- 165
很明显,guava的速度快很多,这个程序如果运行在每天处理大量字符串的服务中,那么性能差异更加明显。我想其中的原因是Splitter返回的是Iterable<String>,而StringUtils.split返回的是一个String[],需要创建新的String对象,导致耗时增加。
如果我们对Splitter对象缓存,那么速度提高更多:
- start = System.currentTimeMillis();
- Splitter s = Splitter.on(',');
- for (int i = 0; i < 1000000; i++) {
- s.split(numberList);
- }
- System.out.println(System.currentTimeMillis() - start);
结果为12,神奇吧,呵呵
别急,结果还没有出来,目前我们还没有对结果进行处理。我们试试对上面的结果进行处理:
- final String numberList = "One,Two,Three,Four,Five,Six,Seven,Eight,Nine,Ten";
- long start = System.currentTimeMillis();
- for (int i = 0; i < 1000000; i++) {
- final String[] numbers = StringUtils.split(numberList, ',');
- for (String number : numbers) {
- number.length();
- }
- }
- System.out.println(System.currentTimeMillis() - start);
- start = System.currentTimeMillis();
- for (int i = 0; i < 1000000; i++) {
- Iterable<String> is = Splitter.on(',').split(numberList);
- for(String s:is) {
- s.length();
- }
- }
- System.out.println(System.currentTimeMillis() - start);
- start = System.currentTimeMillis();
- Splitter sp = Splitter.on(',');
- for (int i = 0; i < 1000000; i++) {
- Iterable<String> is = sp.split(numberList);
- for(String s:is) {
- s.length();
- }
- }
- System.out.println(System.currentTimeMillis() - start);
结果再次令人惊奇:
- 851
- 2967
- 2514
guava比apache 的StringUtils慢3倍。
结论:
很明显,guava把处理时间较长的操作延迟到后面了,前期处理比较快。无论如何,我还是比较倾向于采用guava处理常见的字符串分隔任务,如果你要处理大量分隔后的字符串,且对性能比较关注,那可以使用StringUtils.split。