# Heis的Blog

## 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();
"EnglishBook");
"Commons Cookbook");
"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

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()
+"");
}
->356788;

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();
"book1",10);
"book2",20);

Bag bag2
=new HashBag();
"book2",5);
"book3",10);

"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();
"book1",2);
"book2",1);
"book3",2);
"book4",1);
"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作为内部容器。

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);
"book1");
"book2");

try{
"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);
"book1");
"book2");

try{
"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();
new Long(2));
new Long(20));
new Long(12));
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()));
new Book("book1",Long.valueOf(200)));
new Book("book2",Long.valueOf(7200)));
new Book("book3",Long.valueOf(163)));
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);

"book1");
"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或以下版本）

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

posted on 2010-01-12 22:28 Heis 阅读(3889) 评论(1)  编辑  收藏 所属分类: Jakarta Commons Cookbook读书笔记

## #re: Jakarta Commons Cookbook读书笔记--Commons Collections(容器篇之一)回复更多评论

2010-01-13 11:11 | 朔望魔刃

 只有注册用户登录后才能发表评论。 网站导航: 相关文章: