Iterator接口Iterator模式是用于遍歷集合類的標(biāo)準(zhǔn)訪問方法。它可以把訪問邏輯從不同類型的集合類中抽象出來,從而避免向客戶端暴露集合的內(nèi)部結(jié)構(gòu)。
Iterator模式總是用同一種邏輯來遍歷集合:
for(Iterator it = c.iterater(); it.hasNext(); ) { ... }
奧秘在于客戶端自身不維護(hù)遍歷集合的"指針",所有的內(nèi)部狀態(tài)(如當(dāng)前元素位置,是否有下一個(gè)元素)都由Iterator來維護(hù),而這個(gè)Iterator由集合類通過工廠方法生成,因此,它知道如何遍歷整個(gè)集合。
客戶端從不直接和集合類打交道,它總是控制Iterator,向它發(fā)送"向前","向后","取當(dāng)前元素"的命令,就可以間接遍歷整個(gè)集合。
首先看看java.util.Iterator接口的定義:
public interface Iterator {
boolean hasNext();
Object next();
void remove();
}
依賴前兩個(gè)方法就能完成遍歷,典型的代碼如下:
for(Iterator it = c.iterator(); it.hasNext(); ) {
Object o = it.next();
// 對(duì)o的操作...
}
在JDK1.5中,還對(duì)上面的代碼在語法上作了簡(jiǎn)化:
// Type是具體的類型,如String。
for(Type t : c) {
// 對(duì)t的操作...
}
每一種集合類返回的Iterator具體類型可能不同,Array可能返回ArrayIterator,Set可能返回SetIterator,Tree可能返回TreeIterator,但是它們都實(shí)現(xiàn)了Iterator接口,因此,客戶端不關(guān)心到底是哪種Iterator,它只需要獲得這個(gè)Iterator接口即可,這就是面向?qū)ο蟮耐Α?br>要確保遍歷過程順利完成,必須保證遍歷過程中不更改集合的內(nèi)容(Iterator的remove()方法除外),因此,確保遍歷可靠的原則是只在一個(gè)線程中使用這個(gè)集合,或者在多線程中對(duì)遍歷代碼進(jìn)行同步。
最后給個(gè)完整的示例:
Collection c = new ArrayList();
c.add("abc");
c.add("xyz");
for(Iterator it = c.iterator(); it.hasNext(); ) {
String s = (String)it.next();
System.out.println(s);
}
如果你把第一行代碼的ArrayList換成LinkedList或Vector,剩下的代碼不用改動(dòng)一行就能編譯,而且功能不變,這就是針對(duì)抽象編程的原則:對(duì)具體類的依賴性最小。
HashTable的應(yīng)用非常廣泛,HashMap是新框架中用來代替HashTable的類,也就是說建議使用HashMap,不要使用HashTable??赡苣阌X得HashTable很好用,為什么不用呢?這里簡(jiǎn)單分析他們的區(qū)別。 1.HashTable的方法是同步的,HashMap未經(jīng)同步,所以在多線程場(chǎng)合要手動(dòng)同步HashMap這個(gè)區(qū)別就像Vector和ArrayList一樣。 它也比 HashMap 慢,因?yàn)樗峭降摹?nbsp; 2.HashTable不允許null值(key和value都不可以),HashMap允許null值(key和value都可以)。 3.HashTable有一個(gè)contains(Object value),功能和containsValue(Object value)功能一樣。 4.HashTable使用Enumeration,HashMap使用Iterator。 以上只是表面的不同,它們的實(shí)現(xiàn)也有很大的不同。 5.HashTable中hash數(shù)組默認(rèn)大小是11,增加的方式是 old*2+1。HashMap中hash數(shù)組的默認(rèn)大小是16,而且一定是2的指數(shù)。 6.哈希值的使用不同,HashTable直接使用對(duì)象的hashCode,代碼是這樣的: int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % tab.length; 而HashMap重新計(jì)算hash值,而且用與代替求模: int hash = hash(k); int i = indexFor(hash, table.length);
static int hash(Object x) { int h = x.hashCode();
h += ~(h << 9); h ^= (h >>> 14); h += (h << 4); h ^= (h >>> 10); return h; } static int indexFor(int h, int length) { return h & (length-1); } 以上只是一些比較突出的區(qū)別,當(dāng)然他們的實(shí)現(xiàn)上還是有很多不同的,比如 HashMap對(duì)null的操作。 |
private static Map map = new HashMap();
static {
map.put("bbb", "XXXX");
map.put("aaa", "XXXX");
map.put("cccc", "XXXX");
...................
}
/**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
.................
Set set = map.keySet();
Iterator it = set.iterator();
Date date=new Date();
while (it.hasNext()) {
Object key =it.next();
Object value = map.get(key);
//Interface Iterator 中的三個(gè)方法
boolean | hasNext() Returns true if the iteration has more elements. |
| next() Returns the next element in the iteration. |
void | remove() Removes from the underlying collection the last element returned by the iterator (optional operation). |
//
}