1. 程式人生 > >org.apache.commons.collectionsJDK中不是已經有了Java集合框架了嗎,為什麼還要使用Apache的集合呢?

org.apache.commons.collectionsJDK中不是已經有了Java集合框架了嗎,為什麼還要使用Apache的集合呢?

本文簡要的介紹了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,具有對應的介面實現。 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(String command, Object arg) {
        returnsiebel.consume((String)commandMap.getKey(command), arg);
    }
}
即可以根據key查詢value,也可以根據value查詢key。

org.apache.commons.collections.buffer
這個包中包含了封裝類,直接實現了java.util.Collection介面。因此,任何實現Collection介面的類都可以使用這些封裝類。比較常用的類有PredicatedCollection、CompositeCollection、SynchronizedCollection、TransformedCollection、TypedCollection和UnmodifiableCollection。下表提供了關於這些類的一個概覽:
PredicatedCollection:可以通過使用這個類的例項來追加限制條件,將條件定義成一個獨立的物件,也就是所謂的前提條件,然後作為引數傳送給封裝類的工廠方法。
▶           CompositeCollection:使用這個類可以建立集合的集合,並且當新增或者刪除物件時具有一個統一的檢視。
▶           SynchronizedCollection:可以使既存的集合執行緒安全。
▶           TransformedCollection:當將物件新增到集合時轉換物件的型別。例如由String-->Integer。
▶           TypedCollection:與Java 1.5類似的泛型。
▶           UnmodifiableCollection:使集合的引用不可以被修改。
org.apache.commons.collections.comparators
這個包中包含了很多可複用的類。NullComparator類和FixedOrderComparator是最常用的類。
NullComparator:當對陣列或者列表中的實體進行排序時,將null實體移到底部。
FixedOrderComparator:將一個集合中的順序重新儲存在預定義的列表中。
org.apache.commons.collections.functors
org.apache.commons.collections.iterators
在這個包中包含了很多實現了java.util.Iterator介面的類。比較重要的類有MapIterator、ArrayIterator、CollatingIterator、LoopingIterator和IteratorUtils。需要通過使用IteratorUtils類來使用這個包中的類。
org.apache.commons.collections.keyvalue
這個包中的MultiKey類非常有用。如果想要在應用程式中建立一個域(domain)物件並將它們儲存在一個基於聯合逐漸的map中,就可以通過建立一個MultiKey的例項,使用記錄的主鍵的值作為引數。然後將這個例項傳遞給map來儲存域物件。
這個包中的類的其他用途是儲存locale相關的實體,在這種情況下,實際的主鍵和locale name聯合組成key。
org.apache.commons.collections.list
TreeList、FixedSizeList、NodeCachingLinkedList、CursorableLinkedList、TransformedList和PredicatedList類都是這個包中比較重要的類。它們的javadoc也非常清楚的描述了各自的功能。
org.apache.commons.collections.map
CaseInsensitiveMap、CompositeMap、FixedSizeMap、Flat3Map、LazyMap、LinkedMap、LRUMap、MultiKeyMap、PredicatedMap、SingletonMap和StaticBucketMap類都比較有用。

相關推薦

org.apache.commons.collectionsJDK已經Java集合框架為什麼還要使用Apache集合

本文簡要的介紹了Apache Commons中的collections框架內容。本文主要根據Apache官方網站的overview、userguide以及javadoc翻譯而成。如有轉載,請宣告出處。 Commons Collections: Java集合框架是JDK 1.3對JDK1.2的一個主要的補充。

Spring boot mybatis整合報錯Caused by: org.xml.sax.SAXParseException: 前言允許內容

今天整合Spring boot和mybatis整合的時候,報了這麼一個錯誤! 經過斷點除錯發現錄製進去的xml檔案的二進位制流是空的,也就是說沒有讀到xml檔案,但是又沒有說沒有讀到xml檔案,這點很

SAXParseException:前言允許內容

ins see exceptio 可能 配置文件 clean ada 工作 orm 今天打開eclipse時,顯示:發生了錯誤。請參閱日誌文件D:\eclipse\Workspace\.metadata\.log。然後打開日誌:problems readiing inf

使用 Go 語言開發大型 MMORPG 遊戲服務器怎麽樣?(非常穩定、捕獲所有異常、非常適合從頭開始但大公司已經現成的C++框架、所以會使用)

hive 有效 筆記 序列 優勢 nal 授權 登陸 RR 使用 Go 語言開發大型 MMORPG 遊戲服務器怎麽樣?和C Socket服務器比起來有什麽優劣?可行性怎麽樣? 從2013年起,經朋友推薦開始用Golang編寫遊戲登陸服務器, 配合C++做第三方平臺

將兩個遞增的有序連結串列合併為一個遞增的有序連結串列。要求結果連結串列扔使用原來兩個連結串列的儲存空間另外佔用其他的儲存空間。表允許重複的資料。

語言:C++ #include <iostream> using namespace std; typedef struct LNode { int data; LNode *next; }LNode,*LinkList; //建立連結串列 int CreateList(Li

“Nested exception: 前言允許內容"錯誤處理

最近在做一個小專案,使用org.dom4j.DocumentHelper.parseText方法時一直報錯”Nested exception: 前言中不允許有內容",這個parseText解析的內容是從一個文字檔案中讀出的.程式碼大致如下: String content = FileUtil.rea

Ant將Jmeter的jtl檔案轉為html檔案報“前言允許內容”

build.html <?xml version="1.0" encoding="UTF-8"?> <project name="ant-jmeter-test" default="run" basedir='.'>        <tstam

java-為什麼非靜態內部類static修飾的屬性但卻可以final常量?

 -  例: 1 public class Demo{ 2 int x; 3 class A{ 4 static int a = 0; //這樣寫是不合法的. 5 static final int b=0; //這樣寫是合法的 6

java-為什麽非靜態內部類static修飾的屬性但卻可以final常量?

static變量 虛擬機 修飾 要求 public col 什麽 常量 logs -  例: 1 public class Demo{ 2 int x; 3 class A{ 4 static int a = 0; //這樣寫是不合法

介面靜態程式碼塊

技術方向1: Eclipse平臺技術愛好者,實踐者,5年以上Eclipse外掛、RCP開發經驗,對Eclipse外掛、RCP有深入的瞭解。熟悉Eclipse外掛,RCP,GEF,JDT,AST及IDE開發,瞭解EMF,OSGI,對程式碼自動化生成及MDA等也有一定的經驗和實踐。閱讀和研

《為什麼非靜態內部類static屬性的變數卻可以static final屬性的變數?》

每當我們翻閱有關Java的入門書籍,進入關於內部類的章節時,我們經常可以看到某某書上寫道: ——非靜態實名內部類(成員內部類)中不能含有static修飾的變數,但是可以含有st

Jmeter+Ant執行build.xml常見錯誤:前言允許內容

build.html<?xml version="1.0" encoding="UTF-8"?><project name="ant-jmeter-test" default="run" basedir='.'>       <tstamp>

關於 SAXParseException Content is not allowed in Prolog (前言允許內容)

解析 XML 檔案的時候,如 Mybatis 的 Mapper 檔案,有時會出現 org.xml.sax.SAXParseException 前言中不允許有內容 的異常,英文就是 Content is

Bag集合工具類(apache-commons-collections3.2工具包)在java的使用

 Bag 是在 org.apache.commons.collections 包中定義的介面 ,也是集合的一種擴充工具類,當然結合用JDK中的map類進行相應的邏輯處理,也能實現Bag類的功能,但

讀取xml格式utf-8編碼 和utf-8 無bom編碼格式,出現 前言允許內容的問題

1,java 讀取 xml utf-8 編碼格式的檔案,出現  Caused by: org.xml.sax.SAXParseException; lineNumber: 1; columnNumber: 1; 前言中不允許有內容。     出現這樣的原因, 是因為讀取檔案

關於jsp頁面已經資料的編輯或者修改時部分欄位能修改的問題

首先宣告專案使用的框架是springMVC+mybatis. <form id="editForm" action="<%=basePath%>car/edit"> <

mybatis逆向工程出現XML Parser Error on line 1: 前言允許內容。

今天用nybatis逆向工程時候總是包XML Parser Error on line 1: 前言中不允許有內容。錯誤 但是配置檔案沒有錯誤, 原來是編碼錯誤了 我用記事本開啟編碼變成了utf-8 bom了 改為utf-8即可 或者用notepad++開啟 用utf-8

BUILD FAILED D uild xml 2 前言允許內容

net 零基礎 details nbsp edit build uil .net build.xml 1、錯誤描述 Microsoft Windows [版本 6.1.7601] 版權所有 (c) 2009 Microsoft Corporation。保留所有權利。

IDEA下Maven專案整合Spring和MyBatis出現jdbc.properties is invalid;前言允許內容

在Idea下用Maven管理Spring和MyBatis整合的專案,在Junit測試service層程式碼時不會出錯,但把整個專案釋出到Tomcat時丟擲各種各樣的異常,花了最多時間的異常為: o

C++struct也建構函式與解構函式也可以訪問型別控制以及結構體大小類大小

C++中struct也有建構函式與解構函式,也可以有訪問型別控制,可以用private關鍵字。如下所示: #include <iostream> struct point { public: point():x_(0.0),y_(0.0