您的位置:首页 > 编程语言 > Go语言

google collections介绍

2013-12-27 15:35 288 查看
google collections是google的工程师利用传说中的“20%时间”开发的集合库,它是对java.util的扩展,提供了很多实用的类来简化代码。google collections使用了范型,所以要求jdk1.5以上。它的作者没有像apache commons collections一样照顾老的jdk版本,一个原因是google的jdk基本都是1.5以上,另一个原因是类型转换实在是太难看了。现在的集合库版本是1.0,已经很稳定了,在功能和实现方面也是广泛参考意见(比如java.util之父Josh
Bloch),所以该库的质量可想而知,将来也有可能集成到jdk中。项目地址是http://code.google.com/p/google-collections/,该文对其提供的核心类做简要的介绍。

Immutable Collections

在《effective java》的13条提到immutable class的好处及做法,有兴趣的可以参考该节。在immutable collections方面,java.util.Collections类提供了一系列unmodifiableFoo的静态方法供使用,这些unmodifiableFoo实际上是原有集合的视图包装,所以可以认为新生成的不变集合和原有集合是同一对象,只是不变集合不能调用修改操作。这种效果有时并不是真正想要的,有时需要的是生成的不变集合和原有集合是分离的,原有集合的后续操作不影响不变集合。google
collections就提供了该功能,具体的就包括ImmutableList、ImmutableMap、ImmutableSet等。下面给出一个示例片断:

原有使用java.util.Collections的方法示例:

? List<String> list = new ArrayList<String>(); ? list.add("1"); ? list.add("2"); ? list.add("3"); ? List<String> immutableList = Collections.unmodifiableList(list);


使用com.google.common.collect.ImmutableList示例:

? List<String> immutableList = ImmutableList.of("1","2","3");


com.google.common.collect.ImmutableFoo都是通过调用静态的of方法生成新的不变集合,该方法的参数是个可变数组。因为ImmutableFoo只提供读操作并自己维护数据,所以性能方面会比java.util中集合类有所提高。另外要说的是,不变集合并不能左右其包含的元素是否可变,所以不变集合中的元素最好也是不变的。

Multiset & Multimap

java.util.Set是个无序且元素不重复的集合。而Multiset是个无序但添加元素可重复的集合,对添加的重复元素,以计数表示多少。Multiset的实现也是支持多种类型的(比如Hash、LinkedList等)下面是使用片断:

? Multiset<String> set = HashMultiset.create(); ? set.add("kafka0102"); ? set.add("kafka0102"); ? System.out.println(set.count("kafka0102"));//输出2 ? set.setCount("kafka0102", 5); ? System.out.println(set.count("kafka0102"));//输出5


这个Multiset还是有很多应用场景的,比如统计用户访问计数,没有Multiset,就需要使用如Map来做,每次累加都需要先取出原有的计数值再加一后放回去,自然不如Multiset使用的方便。

Multimap也是很方便实用的集合,对于形如Multimap<K,V>的map,它相当于Map<K,Collection<V>>。如果实用Map来实现Multimap的功能,可想又是对Map的value进行三部曲操作。Multimap的实现也是支持多种类型的(比如Hash、LinkedList等)。使用Multimap的示例代码如下:

? Multimap<String,String> map = HashMultimap.create(); ? map.put("kafka0102","1"); ? map.put("kafka0102","2"); ? System.out.println(map.get("kafka0102"));//输出[2, 1]


BiMap

BiMap(bidirectional map)是个双向的map。java.util.Map是个正向Map,也就是根据key查value,如果需要根据value查key,或者需要反向得到Map<V,K>,BiMap就是很好的选择,否则就需要两个Map来做。它的具体实现类有:EnumBiMap, EnumHashBiMap, HashBiMap, ImmutableBiMap。示例代码如下:

? BiMap<String,String> map = HashBiMap.create(); ? map.put("kafka0102","1"); ? System.out.println(map.get("kafka0102")); ? System.out.println(map.inverse().get("1");//输出反向数据没有提供单独的函数,而是需要调用inverse().get


MapMaker

MapMaker是对ConcurrentMap的builder,它使得ConcurrentMap的key和value能是弱引用或软引用类型。特别的,它提供的makeComputingMap方法能根据key计算出value来,当没有对key来put value时,生成的ConcurrentMap能根据Function计算出value并和key关联上,后续的访问就不需要再次计算。代码示例如下:

? ConcurrentMap<String, Integer> map = new MapMaker() .concurrencyLevel(32).softKeys().weakValues().expiration(30, TimeUnit.MINUTES).makeComputingMap( ? new Function<String, Integer>() { ? public Integer apply(String key  {
?


google collections还提供一些实用的类,具体可参考它的API doc和http://publicobject.com/2007/09/series-recap-coding-in-small-with.html。该文虽行止于此,也很建议大家有时间研究下google collections的实现,这种基础库看起来简单但要实现的优雅、高效是需要很见功夫的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: