技术开发 频道

Google pk Apache:谁的集合库更酷



一. The com.google.common.base Package
    在这部分将讨论一下在com.google.common.base中的这个通用类包。如果我们直接使用过在Java集合框架包java.lang.ref中的任何SoftReference、WeakReference或PlantomReference类,以及使用ReferenceQueue写过代码,我们会为使用Google的这套库而兴奋不已。下面是Google的三个和java.lang.ref包对应的类:

1. FinalizablePhantomReference
2   FinalizableSoftReference
3. FinalizableWeakReference

    上述的三个类扩展了它们各自在Java集合类中对应的类,这些都都可以处理ReferenceQueue,并回调在这些类中定义的finalizeReferent()方法。因为如果当一个对象被垃圾回收器回收后,必须做一些清理工作时,finalizeReferent()方法将是最好的选择。

    例如,假设我们正在使用ImageChunks类来将一个图象二进制数据保存在一个对象中,然后当JVM运行变得缓慢时,GC将清楚这个对象类型。我们可以试着继承这个FinalizableSoftReference类,然后覆盖FinalizeReferent方法。这个方法允许我们在GC清除对象时写一些清除操作的代码。FinalizableSoftReference的最大优势就是我们不需要直接处理ReferenceQueue。
    要注意的是,这个包并不能取代ReferenceQueue,因为它并不是为增强类而设计的。

2. Function接口
    Function接口中的方法将用来进行数据的类型转换,如将String类型转换为Integer类型。Fuction将被使用在com.google.common.collect包中的Maps和Comparators中来执行转换任务。下面是几个非常典型的Function的应用:

(1)  Maps.uniqueIndex(...)使我们在支持Map实例的数据类型之间进行转换。这个谅无立锥之地 产生一个包含key和被转换的值的Map实例。

(2) Comparators.fromFunction(Function<F,T> function)方法可以让我们建立一个Comparator,个Comparator可以将两个值进行比较。Comparator在这个方法中被创建,这些对象将以自然顺序进行比较。

(3) 在Function中的forMap方法可以方便地在一个要进行转换地Map中查询。这个方法在一个Map实例中调用,并返回一个Function。当这个方法被调用时,将使用这个方法的输入参数作为关键字,在Map中查找数据。
    我们可以发现这个Function接口被使用在List、Iterators、Iterator和Functions类中。和Google的这个Function接口相对应的Apache集合类的接口是org.apache.commons.collections.Transformer,它被使用在以下几个类中:

(1). TransformedBag
(2). TransformedBuffer
(3). TransformedList
(4). TransformedSet
(5). TransformedMap

3. Nullable
    Nullable注释类型是一个非常棒的东西。对于很多商业应用程序的开发人员有一个很常见的误会,就是它们的应用程序不能抛出运行时错误。而Nullable允许运行时错误被接受,并以非常简捷的方式来将这个异常和方法绑定。也就是如果一个方法不能接收一个空参数,开发人员可以使用Nullable来执行一个是否为空的检查,以及在方法的第一行抛出一个错误。
 
4. 对象和预处理类(Objects、Preconditions)
    Objects和Preconditions可以在没有Java标准集合类的情况下使用:
 (1). Objects类包含了一系列有用的方法来辅助调用toString、hashCode和其他Object类的方法。在它的内部使用了数组来表示对适当类型的调用。
 (2) Preconditions类是一个非常有用的类,它用来核对传递到一个方法的参数,并抛出一个适当的异常。

5. Predicates
    Predicates可以对扫描一个集合进行建模(如,当我们想扫描所有的雇员对象集合时,并通过salary属性来过滤他们)。使用Predicates可以为我们节省很多写重复代码(这些代码主要是对集合列表中的对象的核对)的时间。

二、com.google.common.collect Package

    这部分将介绍一下Google的这个用于增强Java集合框架的包:com.google.common.collect。

1. BiMap和ClassToInstance类
 
    在集合库中的BiMap接口和Apache的公用集合中的BidiMap接口类似。它允许我们将五个key映射到一个值上,并形成一个整体。因此,key和value应该是唯一的。
    通过对这两个库的比较后发现,Google的HashBiMap和Apache的DaulTreeBidiMap在插入和查询的时间非常类似。然后,TreeBidiMap花了更长时间来插入数据,,但它更节省内存,这主要是因为它并不使用双重映射来表示key和value。
    如果我们的Key和value使用Enum类型,那么我们可以使用com.google.common.collect包中的EnumBiMap类直接建立一个bi-directional映射。但我想这么做的人很少,毕竟将Enum类型映射到Enum类型的意义不大。
    在Google的这套库中并没有和Apache的ClassToInstance 相对应的类,这个类可以用来将一个对象实例映射到它的class类型。
 
2. Comparators
    在Google和Apache的库中都有Comparators,这个接口可以使我们建立一个Comparator来和集合一起使用。如果我们必须在应用程序中大量使用Comparator,可详细看一下google提供文档。这些文档包含了Comparator的所有方法和使用。
    如果我们有两个comparators,并且想综合利用它们获得更佳的结果,可以很方便地使用Comparators.compound。这个方法返回了一个Comparator,这个Comparator将调用其他的comparator,直到发现了非空的结果。
    在org.apache.commons.collections.comparators包中包含了7个预定义的comparators方法。其中一个是org.apache.commons.collections.ComparatorUtils,这个类和com.google.common.collect.Comparators非常类似。和Apache的库不同,Google的这个Comparator将所有的功能定义在了一个类中:Comparators。这个类包含原始比较方法,还有在比较之前转换数据的功能。
 
3. Maps, Lists,和Sets    这三个类:Maps、Lists和Sets分别允许我们很方便地建立一个map、list和set对象,在建立的过程中无需调用构造方法。如我们可以使用下面的代码来替换Map m = new HashMap()。

    Map m = Maps.newHashMap();

    除了建立集合对象外,这些工厂类还有很多实用的方法,主要的方法如下:

1. Maps.immutableMap(...)方法可以让我们建立一个不变的Map,用于保存一个固定的key和value的对集。我们不再需要写4或5行代码来创建一些硬编码的key和value的映射对。
2. List.newArrayList(Iterator itr)方法建立了一个ArrayList对象,并将参数itr和ArrayList对象组合在一起。

在Apache的类库中也可以找到类似的类,如MapUtils、ListUtils和SetUtils。
这套库还包含了其他一些实用的类,如PrimitiveArrays和ObjectArrays,来简化简单类型的使用。PrimitiveArrays包含了有用的方法将List转换为简单类型。这将大大减少我们程序中的重复代码。
0
相关文章