Apache commons 之 Collections :Map

曹浩波
2023-12-01

Commons Collections在Java.util.Map的基础上扩展了很多接口和类,比较有代表性的是BidiMap、MultiMap和LazyMap。跟Bag和Buffer类似,Commons Collections也提供了一个MapUtils。

 

所谓BidiMap,直译就是双向Map,可以通过key找到value,也可以通过value找到key,这在我们日常的代码-名称匹配的时候很方便:因为我们除了需要通过代码找到名称之外,往往也需要处理用户输入的名称,然后获取其代码。需要注意的是BidiMap当中不光key不能重复,value也不可以。

 

所谓MultiMap,就是说一个key不在是简单的指向一个对象,而是一组对象,add()和remove()的时候跟普通的Map无异,只是在get()时返回一个Collection,利用MultiMap,我们就可以很方便的往一个key上放数量不定的对象,也就实现了一对多。目前MultiHashMap已经不再支持,使用MultiMap替代。

 

所谓LazyMap,意思就是这个Map中的键/值对一开始并不存在,当被调用到时才创建,这样的解释初听上去是不是有点不可思议?这样的LazyMap有用吗?我们这样来理解:我们需要一个Map,但是由于创建成员的方法很“重”(比如数据库访问),或者我们只有在调用get()时才知道如何创建,或者Map中出现的可能性很多很多,我们无法在get()之前添加所有可能出现的键/值对,或者任何其它解释得通的原因,我们觉得没有必要去初始化一个Map而又希望它可以在必要时自动处理数据生成的话,LazyMap就变得很有用了。

 

我们还是通过一个具体的例子来说明:

 

packagetest.ffm83.commons.collections;

 

importjava.util.Date;

importjava.util.HashMap;

importjava.util.Iterator;

importjava.util.Map;

 

 

importorg.apache.commons.collections.BidiMap;

importorg.apache.commons.collections.Factory;

import org.apache.commons.collections.LRUMap;

import org.apache.commons.collections.MultiHashMap;

importorg.apache.commons.collections.MultiMap;

importorg.apache.commons.collections.bidimap.DualHashBidiMap;

importorg.apache.commons.collections.map.LazyMap;

importorg.apache.commons.lang.StringUtils;

 

public classMapUsage {

   public static voidmain(String[] args) {

       demoBidiMap();

       demoMultiMap();

       demoLazyMap();

       demoLRUMap();

    }

 

   //双向Map,可以通过key找到value,也可以通过value找到key

    public static voiddemoBidiMap() {

       System.out.println(StringUtils.center("demoBidiMap ", 40, "="));

       BidiMap bidiMap = newDualHashBidiMap();

       bidiMap.put("BJ""Beijing");

       bidiMap.put("SH""Shanghai");

       bidiMap.put("GZ""Guangzhou");

       bidiMap.put("CD""Chengdu");

       System.out.println("Key-Value:BJ = " + bidiMap.get("BJ"));

       System.out.println("Value-Key:Chengdu = " + bidiMap.getKey("Chengdu"));

       System.out.println(StringUtils.repeat("=",40));

    }

 

    //一对多

    public static voiddemoMultiMap() {

       System.out.println(StringUtils.center("demoMultiMap ", 40, "="));

       MultiMap multiMap = new MultiHashMap();

       multiMap.put("Sean""C/C++");

       multiMap.put("Sean""OO");

       multiMap.put("Sean""Java");

       multiMap.put("Sean"".NET");

       multiMap.remove("Sean""C/C++");

       System.out.println("Sean'sskill set: " + multiMap.get("Sean"));

       System.out.println(StringUtils.repeat("=",40));

    }

   

/* 本方法已经不推荐使用,仅用于示例

    有时候需要将一批数据缓存,并且按照最近最少使用的规则淘汰。这时候就应该想到LRUMap

   LRUMap是一种尺寸固定的Map,当它的容量达到最大时采用最近最少使用的规则淘汰相应的元素。*/

   public static voiddemoLRUMap() {

      System.out.println(StringUtils.center("demoLRUMap ", 40, "="));

      LRUMapcache = new LRUMap(5);

 

      cache.put("01""news1");

      cache.put("02""news2");

      cache.put("03""news3");

      cache.put("04""news4");

      cache.put("05""news5");

 

      Stringnews1 = (String) cache.get("01");

      Stringnews2 = (String) cache.get("02");

      Stringnews3 = (String) cache.get("04");

      Stringnews4 = (String) cache.get("03");

      Stringnews5 = (String) cache.get("02");

      Stringnews6 = (String) cache.get("05");

 

      cache.put("06""news6");

 

      Iteratorit = cache.entrySet().iterator();

      while(it.hasNext()) {

         Map.Entryentry = (Map.Entry) it.next();

         System.out.println(entry.getValue());

      }

   }

 

    public static voiddemoLazyMap() {

       System.out.println(StringUtils.center("demoLazyMap ", 40, "="));

       // borrowed from Commons Collection's Javadoc

       Factory factory = newFactory() {

           public Object create() {

                return newDate();

           }

       };

       Map lazy = LazyMap.decorate(new HashMap(),factory);

       System.out.println(lazy.get("NOW"));

       System.out.println(StringUtils.repeat("=",40));

    }

 

}

 

以下是运行结果:

 

============= demoBidiMap ==============

Key-Value: BJ = Beijing

Value-Key: Chengdu = CD

========================================

============= demoMultiMap =============

Sean's skill set: [OO, Java, .NET]

========================================

============= demoLazyMap ==============

Fri Dec 12 13:26:47 CST 2014

========================================

============== demoLRUMap ==============

news 4

news 3

news 2

news 5

news6 

简单说一下这个Factory,它是定义在org.apache.commons.collections包下面的一个接口,用于自定义对象的创建过程。这个有点像是后面我们要讲的Transformer的简化版本,但是也更直接也很好用,至少Commons Collections通过它向开发人员开放了一个可以方便控制对象创建细节的接口。

 类似资料: