Jakarta Commons Cookbook讀書筆記系列

Jakarta Commons Cookbook讀書筆記--Commons Collections(容器篇之一)

Jakarta Commons Cookbook讀書筆記系列html

3.5 Iterator的擴展java


3.5.1 循環迭代器LoopingIterator
apache

import org.apache.commons.collections.iterators.LoopingIterator;

List books=new ArrayList();
        books.add("EnglishBook");
        books.add("Commons Cookbook");
        books.add("Who Moved My Cheese");
        //當迭代到最後的元素後,再返回第一個元素從新循環,直至達到迭代次數爲止
        LoopingIterator iterator=new LoopingIterator(books);
        for(int i=0;i<5;i++){
            String book=(String)iterator.next();
            System.out.print(book+";");
        }
->EnglishBook;Commons Cookbook;Who Moved My Cheese;EnglishBook;Commons Cookbook;oop


3.5.2 ArrayList迭代器ArrayListIterator 
能夠自定義範圍地遍歷性能

import org.apache.commons.collections.iterators.ArrayListIterator;
 
String[] arrays=new String[]{"a","b","c","d","f"};
        //遍歷下標爲1到4的元素
        Iterator iterator=new ArrayListIterator(arrays,1,4);
        while(iterator.hasNext()){
            System.out.print(iterator.next()+"; ");
        }
->b; c; d; 
this


3.5.3 篩選迭代器FilterIterator 
使用Predicate篩選,關於Predicate的介紹,請看個人這系列的上一篇文章Jakarta Commons Cookbook讀書筆記--Commons Collections(函子篇)lua

import org.apache.commons.collections.iterators.FilterIterator;
import org.apache.commons.collections.Predicate;

List list=new ArrayList(Arrays.asList(new Integer[]{7,9,35,67,88}));
       
        //過濾出大於30的元素
        Predicate predicate=new Predicate(){           
            public boolean evaluate(Object object){
                int num=((Integer)object).intValue();
                return num>30;
            }
        };
        Iterator iterator=new FilterIterator(list.iterator(),predicate);
        while(iterator.hasNext()){
            System.out.print(iterator.next()+"; ");
        }
->35; 67; 88; 
spa


3.5.4 過濾重複的元素UniqueFilterIterator.net

List list=new ArrayList(Arrays.asList(new String[]{"a","b","c","b","a"}));
       
        Iterator iterator=new UniqueFilterIterator(list.iterator());
        while(iterator.hasNext()){
            System.out.print(iterator.next()+"; ");
        }
->a; b; c;orm


3.6 使用Bag


Bag是這樣的一種容器,它可以存儲多個邏輯相等(即equals()爲true,並且hash()相等)的元素,並能夠統計它們的個數。


3.6.1 高性能的HashBag

import org.apache.commons.collections.bag.HashBag;

Bag bag1=new HashBag();
        bag1.add("book1",10);
        bag1.add("book2",20);
       
        Bag bag2=new HashBag();
        bag2.add("book2",5);
        bag2.add("book3",10);
       
        bag1.add("book1");
        bag1.remove("book1",2);   
        //減去bag2內相應元素的數量
        bag1.removeAll(bag2);
       
        System.out.println("book1: "+bag1.getCount("book1"));
        System.out.println("book2: "+bag1.getCount("book2")+"\n");
       
        //bag1保留bag2內的元素,簡單來講就是求交集
        bag1.retainAll(bag2);
        System.out.println("book1: "+bag1.getCount("book1"));
        System.out.println("book2: "+bag1.getCount("book2"));
        System.out.println("book3: "+bag1.getCount("book3"));
->
book1: 9
book2: 15

book1: 0
book2: 5
book3: 0


3.6.2 TreeBag能夠保存加入元素的順序

import org.apache.commons.collections.bag.TreeBag;

Bag bag1=new TreeBag();
        bag1.add("book1",2);
        bag1.add("book2",1);
        bag1.add("book3",2);
        bag1.add("book4",1);
        bag1.add("book5",1);
       
        Iterator iterator=bag1.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
->
book1
book1
book2
book3
book3
book4
book5


HashBag內部原理是使用一個HashMap看成內部容器,key爲加入的對象,對應的value是對象的次數。同理TreeBag使用TreeMap做爲內部容器。
需 要注意的是雖然Bag繼承了Collection,可是它的removeAll(),containsAll(),add(),remove()和 retainAll()方法並不嚴格遵循Collection接口的規範。例如removeAll方法根據規範是移除全部的元素,而Bag的 removeAll是帶參數的,只移除參數包含的元素。 

3.7 用於臨時數據轉移的Buffer


Buffer相似於java5.0中的Queue,是個先進先出(First-in First-out)的數據容器。


3.7.1 無尺寸緩衝區UnboundFifoBuffer和有尺寸緩衝區BoundedFifoBuffer

import org.apache.commons.collections.buffer.BoundedFifoBuffer;

Buffer bBuffer=new BoundedFifoBuffer(2);
        bBuffer.add("book1");
        bBuffer.add("book2");
        try{
            bBuffer.add("book3");
        }catch(BufferOverflowException e){
            System.out.println("Buffer is over flow");
        }
        //移除第一個加入的元素
        bBuffer.remove();
        Iterator iterator=bBuffer.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
->
Buffer is over flow
book2


import org.apache.commons.collections.buffer.UnboundedFifoBuffer;

Buffer bBuffer=new UnboundedFifoBuffer(2);
        bBuffer.add("book1");
        bBuffer.add("book2");
        try{
            bBuffer.add("book3");
        }catch(BufferOverflowException e){
            System.out.println("Buffer is over flow");
        }
        //移除第一個加入的元素
        bBuffer.remove();
        Iterator iterator=bBuffer.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
->
book2
book3


3.7.2 帶優先級的緩衝區PriorityBuffer 
按照數值從小到大排列

import org.apache.commons.collections.buffer.PriorityBuffer;

Buffer pBuffer=new PriorityBuffer();
        pBuffer.add(new Long(2));
        pBuffer.add(new Long(20));
        pBuffer.add(new Long(12));
        pBuffer.add(new Long(4));
       
        Iterator iterator=pBuffer.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
->
2
4
12
20


PriorityBuffer容許使用Comparator來排列優先順序,關於Comparator,請看個人這系列的上一篇文章Jakarta Commons Cookbook讀書筆記--Commons Collections(函子篇) 

import java.util.Comparator;
//按照銷售數量從大到小排列
public class RecommandComparator implements Comparator {

    public int compare(Object o1, Object o2) {
        int result=-1;
        if(o1 instanceof Book && o2 instanceof Book){
            Book book1=(Book)o1;
            Book book2=(Book)o2;
           
            result=book1.getSalsNum().compareTo(book2.getSalsNum());           
        }
        return result;
    }
}


import org.apache.commons.collections.comparators.ReverseComparator;
import org.apache.commons.collections.buffer.PriorityBuffer;

Buffer pBuffer=new PriorityBuffer(new ReverseComparator(new RecommandComparator()));
        pBuffer.add(new Book("book1",Long.valueOf(200)));
        pBuffer.add(new Book("book2",Long.valueOf(7200)));
        pBuffer.add(new Book("book3",Long.valueOf(163)));
        pBuffer.add(new Book("book4",Long.valueOf(569)));
       
        Iterator iterator=pBuffer.iterator();
        while(iterator.hasNext()){
            Book book=(Book)iterator.next();
            System.out.println(book.getName()+":"+book.getSalsNum());
        }
->
book2:7200
book4:569
book3:163
book1:200

3.7.3 使用阻塞式緩衝區BlockingBuffer 
BlokingBuffer裝飾一個Buffer實例,並使其處於阻塞狀態,只要有對象加入則立刻處理。當一個進程調用以BlockingBuffer的get()和remove()方法時,將不返回任何值,直到它有一個對象返回。

import org.apache.commons.collections.Buffer;

public class BufferListener implements Runnable{
    private Buffer buffer;
   
    public BufferListener(Buffer buffer){
        this.buffer=buffer;
    }
   
    public void run() {
        while(true){
            String msg=(String)buffer.remove();
            System.out.println(msg);
        }
    }

   
}


import org.apache.commons.collections.buffer.BlockingBuffer;

Buffer buffer=BlockingBuffer.decorate(new UnboundedFifoBuffer());
        BufferListener listener=new BufferListener(buffer);
        Thread listenerThread=new Thread(listener);
        listenerThread.start();
       
        buffer.add("book1");
        buffer.add("book2");

->
book1
book2


3.8 Map的擴展


3.8.1 使用MultiMap實現一鍵存儲多個值 
MultiValueMap會使用一個ArrayList來保存同一個鍵的全部值

import org.apache.commons.collections.MultiMap;
import org.apache.commons.collections.map.MultiValueMap;

MultiMap map=new MultiValueMap();
        map.put("key", "value1");
        map.put("key", "value2");
        map.put("key", "value2");
        System.out.println((Collection)map.get("key"));
->[value1, value2, value2]


3.8.2 使用BidiMap實現根據值檢索鍵 
DualHashBidiMap使用兩個HashMap來保存鍵值對,其中一個正常保存鍵值對,另外一個反過來保存值對應的鍵。

import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;

BidiMap map=new DualHashBidiMap();
        map.put("key1", "value");       
        System.out.println(map.get("key1"));
        System.out.println(map.inverseBidiMap().get("value"));
->
value
key1

DualTreeBidiMap是能夠記住加入順序的BidiMap,其內部使用TreeMap來保存鍵值對。

3.8.3 大小寫不敏感的CaseInsensitiveMap

import org.apache.commons.collections.map.CaseInsensitiveMap;
CaseInsensitiveMap map=new CaseInsensitiveMap();
        map.put("KEY", "value");.
                map.put("key", "value2");
        System.out.println(map.get("key"));
->value2


3.8.4 指定鍵和值類型(JDK1.4或如下版本) 
若是你使用JDK1.4或如下的版本,你若是須要指定鍵或值的類型,可使用TypeMap來裝飾。

import org.apache.commons.collections.map.TypedMap;

Map map=TypedMap.decorate(new HashMap(), String.class, String.class);
        map.put("key", "value");
        //加入非指定的類型會拋出IllegalArgumentException,程序會中止運行
        map.put("key2", new Integer(12));


3.8.6 根據鍵自動生成值的Map

import org.apache.commons.collections.map.LazyMap;
Transformer upperFirstLetter=new Transformer(){
            public Object transform(Object object){
                String name=(String)object;
                String result=name;
                if(name!=null&&!"".equals(name)){
                    result=name.substring(0,1).toUpperCase()

+name.substring(1);
                }
                return result;
            }
        };
       
        Map map=LazyMap.decorate(new HashMap(), upperFirstLetter);        System.out.println(map.get("heis"));->Heis

相關文章
相關標籤/搜索