Apache Commons Collections

來源:互聯網
上載者:User
Apache Commons Collections 標籤: collectionsapachehashmapcommandobjectjavadoc 2012-05-09 10:13  1070人閱讀  評論(0)  收藏  舉報   分類: Java編程(74) 

目錄(?)[+] 原文http://blog.csdn.net/sunjavaduke/archive/2008/03/24/2214806.aspx 本文簡要的介紹了Apache Commons中的collections架構內容。本文主要根據Apache官方網站的overview、userguide以及javadoc翻譯而成。如有轉載,請聲明出處。 Commons Collections: Java集合架構是JDK 1.3對JDK1.2的一個主要的補充。Java集合架構套件含了很多強大的資料結構,這些資料結構加快了很多重要的Java程式的開發。從那之後,集合架構就已經成為Java處理集合的公開標準。 Commons-Collections以JDK的集合架構為基礎,提供了新的介面、實現以及工具。它具有以下特點: ®        Bag介面:適用於包含一個對象的多個拷貝的集合 ®        Buffer介面:適用於具有順序的集合類,例如FIFOs(先進先出) ®        BidiMap(雙向映射):可以通過值尋找鍵,也可以通過鍵尋找值 ®        Map迭代器:提供了對映射的快速迭代 ®        對類型檢查進行了封裝,確保特定類的執行個體可以被添加到集合中 ®        對轉換進行了封裝,將集合中的對象轉換成被加入時的類型 ®        對集合進行組合,使多個集合看起來就像一個集合一樣 ®        有序映射和set,保持元素添加時的順序,包括一個基於LRU的map ®        標識映射可以給予對象的==來比較對象,而不是基於equals方法 ®        引用映射可以允許鍵and/or值可以有控制的進行回收 ®        很多比較子的實現 ®        很多迭代器的實現 ®        從數組或者枚舉到集合的適配器 ®        用來測試或者建立典型set理論的集合屬性,例如與、或、閉包 使用者指南: Commons-Collections為了協助日複一日的編程,提供了大量的類。本部分主要介紹了一些Collections的關鍵特性。 注意同步 Commons-Collections使用了和標準Java集合類似的同步設計方法。如果不添加額外的同步方法,大多數關於集合、映射和bag的實現都不是安全執行緒的。集合的synchronizeXXX方法就是這些實現中的一種方式,可以使集合在多線程的應用程式中被同步。 類層次的javadoc應該指出如果沒有額外的同步機制,在進行多線程訪問時,某個特定的實現是否是安全的。如果沒有特別指出是安全執行緒的,那麼就被認為是需要進行同步的。 工具類: 每個主要的集合介面都有一個Utility類。因此,Set和SortedSet介面的Utility類就是SetUtils。這些Utility類提供了操作集合類型的共通方法。 基本的方法都包含在兩個根集合介面的Utility類中,即CollectionUtils和MapUtils。因為所有的其他集合介面都整合Collection或者Map,所以CollectionUtils和MapUtils可以被擴充使用。共同的方法包括交集操作、計數操作、迭代操作、邏輯操作和類型強制轉換操作等。同時,utility類還提供了對集合封裝類的訪問,這與JDK Collections類的方式類似。 Maps: Map迭代 JDK中的Map介面很難進行迭代。API使用者總是需要通過EntrySet或者KeySet進行迭代。Commons-Collectons現在提供了一個新的介面—MapIterator來允許對maps進行簡單的迭代。 IterableMap map = new HashMap(); MapIterator it = map.mapIterator(); While(it.hasNext()){        Object key = it.next();        Object value = it.getValue();        It.setValue(newValue); } 有序Map Commons-Collections為maps提供了一個新的介面,OrderedMap,這個介面是有順序的,但是並沒有進行排序。LinkedMap和ListOrderedMap(封裝器)是這個介面的兩種實現。這個介面支援map迭代,同時允許對map進行前向迭代和反向迭代。 OrderedMap map = new HashMap(); map.put(“FIVE”,5); map.put(“SIX”,6); map.put(“SEVEN”,7); map.firstKey();                   //returns “FIVE” map.nextKey(“FIVE”);         //returns “SIX” map.nextKey(“SIX”);           //returns “SEVEN” BidDirectional Maps雙向映射 Commons-Collections提供了新的介面層次,用於支援雙向的映射,即BidiMap介面。可以通過key來尋找value,也可以通過value來尋找key。 BidiMap bidi = new TreeBidiMap(); bidi.put(“SIX”,”6”); bidi.get(“SIX”);            //returns “6” bidi.getKey(“6”);          //returns “SIX” bidi.removeValue(“6”);              //removes the mapping BidiMap inverse = bidi.inverseBidiMap();              //returns a map with keys and values swapped 對於有序的和排序的雙向map,也公用了對應的介面。對於每種雙向map類型都提供了介面的實現。 Queues&Buffers 隊列和緩衝 Buffer介面用來支援隊列和緩衝。這些介面表示集合可以定義刪除的順序。 Buffer buffer = new UnboundedFifoBuffer(); buffer.add(“ONE”); buffer.add(“TWO”); buffer.add(“THREE”); buffer.remove();   //removes and returns the next in order,”ONE” as this is a FIFO buffer.remove();   //removes and returns the next in order,”TWO” as this is a FIFO FIFO(隊列)、LIFO(堆棧)和Priority(根據比較子的順序)的介面實現已經被提供。 Bags Bag介面用於支援bag。它用於表示包含了一個對象的多個拷貝的結合。 Bag bag = new HashBag(); bag.add(“ONE”,6);             //add 6 copies of “ONE” bag.remove(“ONE”,2);              //removes 2 copies of “ONE” bag.getCount(“ONE”);              //returns 4 對於排序和為排序的Bag,具有對應的介面實現。 下面是對Internet中一篇文章的翻譯,原文出處: http://www.devx.com/Java/Article/29392/0/page/3 JDK中不是已經有了Java集合架構了嗎,為什麼還要使用Apache的集合呢。這是因為Apache的集合時對JDK集合的一個補充和增強,它提供了更多的介面和實作類別。甚至於它應該成為JDK的一部分。 下面是一些筆者比較喜歡的特性: ®        bag介面 ®        固定大小的map、LRU (最近最少使用演算法)map和雙重(dual)map ®        對象數組和map的迭代器 ®        map的MultiKey ®        大量的工具類,提供了使用API的捷徑 ®        封裝器,對大多數類提供了自訂的方法 Collections類根據下面列舉的包結構進行組織: org.apache.commons.collections org.apache.commons.collections.bag org.apache.commons.collections.bidimap org.apache.commons.collections.buffer org.apache.commons.collections.collection org.apache.commons.collections.comparators org.apache.commons.collections.functors org.apache.commons.collections.iterators org.apache.commons.collections.keyvalue org.apache.commons.collections.list org.apache.commons.collections.map org.apache.commons.collections.set org.apache.commons.collections 這個包中定義了由其他包實現的介面、作為工廠類(可以執行個體化集合類或者集合的封裝類)的共通類。一些比較重要的類有ArrayStack、BeanMap、ExtendedProperties、FastArrayList、FastHashMap和FastTreeMap。這些類的細節包含在Javadoc中,下面只是簡要的介紹各個類在實際中的應用: ArrayStack:ArrayStack類實現了Stack介面,基於ArrayList用來在單線程環境中使用。例如,如果想在一個方法中使用Stack進行一些處理,這個類在效能上會比Stack(JDK1.4.2中使用Vector)好一些。 BeanMap:就像Swing GUI中的JButton一樣,使用BeanMap,甚至可以將一個map作為一個JavaBean來進行處理。當在設計用來顯示資料來源或者應用程式配置屬性的GUI時,map可以在螢幕上被拖放(D&D)。 ExtendedProperties:這是一個非常有用的類。它和java.util.Properties類似,包含了一個用於載入配置資訊的load方法,但是這個類有以下的好處: # 屬性值可以分布在多行 # 提供了用於擷取非字串值的方法。例如,getFload方法用於擷取一個fload類型的值。這樣就不需要使用wrapper方法來轉換擷取的字串值了。 FastArrayList, FastHashMap, FastTreeMap:這些類可以在多線程環境中使用,如果存在很多隻讀操作的話。這些類是分別基於ArrayList、HashMap和TreeMap的。 org.apache.commons.collections.bag 如果需要將一個對象的多個拷貝添加到一個List中時,這個包下面的類就變得非常有用了。在這種情況下,很多開發人員會將對象添加到一個ArrayList中,然後每天加一次都要進行一下迭代,來判斷是否添加了給定類型的對象。線上購物車是這種情況的一個實際的需求。這種方法的缺點是記憶體和速度上的不足。 解決上述需求的一個比較好的設計就是只儲存一個對象的拷貝,而在添加同樣類型的實體時,只是增加計數器的值。HashBag和TreeBag類(分別基於HashMap和TreeMap)很好的滿足了這個需求。

如下面的例子所示:
package in.co.narayanan.commons.collections.bag;
import junit.framework.TestCase;
import org.apache.commons.collections.Bag;
import org.apache.commons.collections.bag.HashBag;
/**
* This domain represents an order placed by the customer.
* 
* @author Narayanan A R
*/
public class Order {
       private Bag orderedProducts;
       public Order() {
              orderedProducts = new HashBag();
       }
       public void addProduct(Product p) {
              orderedProducts.add(p);
       }
       public int countWindowsLicenses() {
              return orderedProducts.getCount(Product.WINDOWS);
       }
       public int countLinuxLicenses() {
              return orderedProducts.getCount(Product.Linux);
       }
}
class Product {
       //OsType is an enum
       public static final Product WINDOWS = new Product(OsType.WINDOWS);
       public static final Product LINUX = new Product(OsType.LINUX);
       public static final Product MAC = new Product(OsType.MAC);
       public static final Product HPUNIX = new Product(OsType.HPUNIX);
       private int quantity;
       private int version;
       private float prize;
       private OsType type;
       public Product(OsType type) {
              this.type = type;
       }
       public int getQuantity() {
              return quantity;
       }
       public void setQuantity(int quantity) {
              this.quantity = quantity;
       }
       public int getVersion() {
              return version;
       }
       public void setVersion(int version) {
              this.version = version;
       }
       public float getPrize() {
              return prize;
       }
       public void setPrize(float prize) {
              this.prize = prize;
       }
       public OsType getType() {
              return type;
       }
       public void setType(OsType type) {
              this.type = type;
       }
       @Override
       public boolean equals(Object o) {
              if (o instanceof Product) {
                     return ((Product) o).getType().equals(this.getType());
              }
              return super.equals(o);
       }
       @Override
       public int hashCode() {
              return type.hashCode();
       }
       @Override
       public String toString() {
              return type.toString();
       }
}
class TestOrder extends TestCase {
    public void testOrder() {
        Order order = new Order();
        order.addProduct(new Product(OsType.WINDOWS));
        order.addProduct(new Product(OsType.WINDOWS));
        order.addProduct(new Product(OsType.WINDOWS));
        order.addProduct(new Product(OsType.LINUX));
        order.addProduct(new Product(OsType.LINUX));
        order.addProduct(new Product(OsType.HPUNIX));
        order.addProduct(new Product(OsType.MAC));
        int licenses;
        licenses = order.countWindowsLicenses();
        assertEquals(3, licenses);
        licenses = order.countLinuxLicenses();
        assertEquals(2, licenses);
    }
}
通過調試,運行到上述紅色行時,order的成員變數orderedProducts的內容為:(toString顯示內容)
[2:LINUX,1:MAC,1:HPUNIX,3:WINDOWS]
即實際上只儲存了一個對象的拷貝,然後使用數字進行標識個數。
而orderedProducts的成員HashMap對象的size為4。
org.apache.commons.collections.bidimap

很多Java開發人員通過使用兩個HashMap來擷取一個索引值,方法是將一個值作為鍵傳遞到另外一個HashMap。正常情況下,需要對同等的處理名字和值,在這種情況下,就是值也可以做為鍵(因為在map中鍵是唯一的,而值是可以不唯一的)。
關於org.apache.commons.collections.bidimap的例子是一個原型適配器,整合了PeopleSoft和Siebel命令列處理引擎,假定一個引擎中的每個命令在另外一個中都有同樣的對應。可以在in.co.narayanan.commons.collections.bidimap中找到相關的類。可以通過SiebelPeopleSoftConnector來瞭解這些類,SiebelPeopleSoftConnector作為適配器,並包含了BidiMap對象。當收到處理Siebel命令的請求後,就從BidiMap擷取對應的PeopleSoft命令,然後傳送給PeopleSoft命令引擎。反之亦然。範例代碼中只包含應用程式的一個輪廓。
/**
*Definescontractforthesystemstoconsumeagiven
*command.
*
*@authorNarayananAR
*/
publicinterface ICommandConsumer {
    Object consume(String command, Object arg);
}
class SiebelCommandConsumer implements ICommandConsumer {
    public Object consume(String command, Object arg) {
        System.out.println("Processing Siebel command:" + command);
        System.out.println("Arg:" + arg);
        return"SIEBEL:" + command + "-SUCCESSFUL";
    }
}
class PeopleSoftCommandConsumer implements ICommandConsumer {
    public Object consume(String command, Object arg) {
        System.out.println("Processing PeopleSoft command:" + command);
        System.out.println("Arg:" + arg);
        return"PEOPLESOFT:" + command + "-SUCCESSFUL";
    }
}
import org.apache.commons.collections.bidimap.TreeBidiMap;
import org.apache.commons.collections.BidiMap;
/**
*Responsibleforadaptingboththesystem'scommands.
*
*@authorNarayananAR
*/
publicclass SiebelPeopleSoftConnector {
    private ICommandConsumer peopleSoft;
    private ICommandConsumer siebel;
    private BidiMap commandMap;
    public SiebelPeopleSoftConnector(ICommandConsumer peopleSoft,
                                     ICommandConsumer siebel) {
        this.peopleSoft = peopleSoft;
        this.siebel = siebel;
        commandMap = prepareCommandMapping();
    }
    private BidiMap prepareCommandMapping() {
        BidiMap map = new TreeBidiMap();
        map.put("start", "init");
        map.put("exit", "quit");
        map.put("delete", "remove");
        return map;
    }
    /**
     *DelegatesthecalltothePeopleSoftcommandenginebyfetchingthemappedcommand.
     *
     *@paramcommandSiebelcommand
     *@paramargArgumentifany
     *@returnResultreturnedfromPeopleSoftcommandengine
     */
    public Object processSiebelCommand(String command, Object arg) {
        returnpeopleSoft.consume((String)commandMap.get(command), arg);
    }
    /**
     *DelegatesthecalltotheSiebelcommandenginebyfetchingthemappedcommand.
     *
     *@paramcommandPeopleSoftcommand
     *@paramargArgumentifany
     *@returnResultreturnedfromSiebelcommandengine
     */
    public Object processPeopleSoftCommand(Str

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.