很久没更新文章了,最近忙于系统上线,同时拾起来一年多没写过的Java,做一些平台化,系统组件的开发。之后准备通过拜读一下HBase的代码来提升自己对Java的认识。以前写c/c++时,可选的Base库并不是特别多,boost、libev、libaio取之可数。最近用到了写Java的基础框架的库(SSH之类的就不说了),比如MyBaties、DBCP、Guice、Guava等。准备拿出些比较经典的和大家分享一下,本文只起到抛砖引玉的作用,如有细节问题,可回帖一起讨论
1、apache common http://commons.apache.org
2、Google Guava http://code.google.com/p/guava-libraries/
3、Google DI框架 Guice http://code.google.com/p/google-guice/
1、一提到common库,大家第一个肯定Apache有个org.apache.common.*的集合(http://commons.apache.org),里面继承了各种数据结构、文件IO、网络IO、Hash、断言等等很多东西。大致列出了一个比较常用的:
codec : 编码解码算法,如Base64、UrlEncode等
Collections : 扩展jdk的collections集合
Compress : zip、tar等压缩算法
Deamon : Unix后台daemon精灵进程
Dbcp : 可扩展的数据库连接池
JCS : Java带LRU的Cache,可以看成是一个固定大小可自动淘汰key的Map
Pool : “池”化的实现,例如数据库连接池、线程池、对象池都可以基于此进行扩展
可以看出,其实很多功能性的,平时开发中很可能遇到的但jdk中不提供的,一般都可以找到。或者直接用或者直接扩展成自己的类。一般能从中找到的就不要自己实现,因为不一定更好,而且还需要时间的考验。关于Apache Common开发过java的都不陌生,如果你用了SSH就间接的使用了它。这里不做过多讨论了,如果有兴趣可以针对细节再留言探讨哈。
2、Apache Common是一个时间比较久的框架了,Google针对基础框架退出了自己的类库,并且开源出来(http://code.google.com/p/guava-libraries/),名为“Guava”。它在部分功能上其实是ApacheCommon的一个子集,但在性能上做了很多优化,并且针对并发和大规模系统开发做了很多新的策略(如CopyOnWrite、Immutable、SkipList)等。虽然有些类和java.util.concurrent有些重叠,但是在一般环境下都可以替代。
Google比较喜欢java的"链式编程“,很多类都是支持链式的,比如Joiner.on("#").skipNulls().join("a","b","c")。不太熟悉的同学可以Google之。本文针对其中几个特别的实现,以及适用场景进行讲解:
Preconditions : 类似Assert的预言,但处理方式是抛出异常,比如checkNotNull(obj),如果obj是null则会抛出NullPtrException
ImmutableSet/Map : 不可变的set和map,存储constant常量的集合,元素内容和个数不再变化,这里就可以做很多空间和检索上的优化。
BiMap : jdk的map一般是通过key检索value,如果反查的话,最简单的就是构造另一个同步的map把value存成key,而BiMap支持双向检索,通过reverse反转关系。
Table : 支持二维索引的Map,比如我们有个Map<String,Map<String,Integer>>,通过两个字符串定位int,使用起来很麻烦,Table支持row和column的概念,在横“向”和“纵向”两个纬度来索引。
RangeSet : 区间型的集合,比如想得到一个1~100的数字的集合,最简单的做法就是for循环100次然后put进容器。rangeset支持add(range.open(1,100))这样类似php range()函数一样。
ListenableFuture : jdk提供了一个java.util.concurrent.Future的异步操作,可以非阻塞的执行一个Runable任务,但Future有一个问题,必须同步的调用get()取等结果或者直接获得结果,在逻辑上还是需要同步的操作,ListenableFuture通过addListener()的方式直接“回调”实现的方法,可以做到完全异步。
StringJoiner : 如果用过python的同学,应该很喜欢字符串的join()函数,实现字符串的按规律拼接。如
Joiner.on("#").skipNulls().join("a","b","c");// 返回"a#b#c"
Hashing : 如果用过Java自带的MD5的同学,经常看到比较繁琐的代码,导入security下好多包,然后静态初始化,然后getInstance获得算法实例。而Guava的md5非常干净,只需要:
Hashing.md5().newHasher().put("123123123");
BloomFilter : 布隆过滤,可通过设置希望的准确率,数据总量来初始化 :
BloomFilter<Person> bf = BloomFilter.create(object, 500, 0.01);// 0.01为可能错误判断的概率
EventBus : 接口简单的pub/sub的只需要一个register和Subcribe的注解即可。
3、还有一个Google的common框架不得不提,就是Google的依赖注入(Dependency Injector)框架Guice,这是个Google正在大规模使用的lib。主要提供代码级的依赖注入和AOP切面。
Apache的Spring可谓是DI的经典之作,但由于其功能太多,而且和ssh框架绑定比较多,如果只使用DI和AOP,那么还是推荐大家使用Guice。而且Guice不像Spring是用xml来描述,是通过注解来注入,所以做到了动态注入(代码可控)。给出一个DI的例子:
public class HelloWorld implements HelloWorld { @Override String sayHello() {return "hello world";} }
@ImplementedBy(HelloWorldImpl.class) public interface HelloWorld { String sayHello(); }
Injector inj= Guice.createInjector(); HelloWorld hw = inj.getInstance(HelloWorld.class); System.out.println(hw.sayHello());
看起来是不是很方便,当然,Guice还支持多种多样的注入方式,大家可以看看http://code.google.com/p/google-guice/来了解。