Guava 的 FAQ 部分有专门解答:
Why did Google build all this, when it could have tried to improve the Apache Commons Collections instead?
The Apache Commons Collections very clearly did not meet our needs. It does not use generics, which is a problem for us as we hate to get compilation warnings from our code. It has also been in a "holding pattern" for a long time. We could see that it would require a pretty major investment from us to fix it up until we were happy to use it, and in the meantime, our own library was already growing organically.
An important difference between the Apache library and ours is that our collections very faithfully adhere to the contracts specified by the JDK interfaces they implement. If you review the Apache documentation, you'll find countless examples of violations. They deserve credit for pointing these out so clearly, but still, deviating from standard collection behavior is risky! You must be careful what you do with such a collection; bugs are always just waiting to happen.
Our collections are fully generified and never violate their contracts (with isolated exceptions, where JDK implementations have set a strong precedent for acceptable violations). This means you can pass one of our collections to any method that expects a Collection and feel pretty confident that things will work exactly as they should.
简单地说:
Apache Commons Collections 3.x 不支持泛型,Guava 支持
Guava 实现了 JDK 的标准接口,而 Apache Commons Collections 3.x 有很多违反标准的地方
Apache Commons Collections 4.x 的发行注记如下:
Major changes since 3.2.1
Use of generics and other language features introduced in Java 5 (varargs, Iterable)
Removed deprecated classes / methods and features which are now supported by the JDK
Replaced Buffer interface with java.util.Queue
Added concept of split maps with respective interfaces Put / Get (see also package splitmap)
Added new Trie interface together with an implementation of a Patricia Trie
从 4.x 开始,Apache Commons Collections 开始使用 JDK 5 的特性(包括泛型),此外也去除、添加了很多内容
各有千秋, 我主要使用 Apache Commons ,辅助使用 Google guava
但是细节方法上还是有区别的, 比如
GoogleGuava Splitter 对比 Apache StringUtils
apache commons的StringUtils提供的常用功能介绍,但是google的guava也提供了一些字符串处理的常见功能,所以,将对两者的字符串分割函数做一次比较详细的对比(结果比较surprise)。
区别
首先看基本的使用方法:
// Apache StringUtils...
String[] tokens1= StringUtils.split("one,two,three",',');
// Google Guava splitter...
Iteratabletokens2 = 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
大部分使用分隔符的情况是我们需要对字符串按照分隔符进行遍历处理,仅此而已。
下面就是常用的代码性能对比的例子:
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
如果我们对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,神奇吧,呵呵