Jakarta Commons Cookbook读书笔记--Commons Collections(容器篇之一)

Jakarta Commons Cookbook读书笔记--Commons Collections(容器篇之一)

Jakarta Commons Cookbook读书笔记系列

3.5 Iterator的扩展


3.5.1 循环迭代器LoopingIterator

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;


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;


3.5.3 筛选迭代器FilterIterator
使用Predicate筛选,关于Predicate的介绍,请看我的这系列的上一篇文章Jakarta Commons Cookbook读书笔记--Commons Collections(函子篇)

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 ;


3.5.4 过滤重复的元素UniqueFilterIterator

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;


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


Jakarta Commons Cookbook读书笔记系列



 



程序员的一生其实可短暂了,这电脑一开一关,一天过去了,嚎;电脑一开不关,那就成服务器了,嚎……

你可能感兴趣的:(Jakarta Commons Cookbook读书笔记--Commons Collections(容器篇之一))