三、測試Queue類
下列類用於測試"泛型"隊列。
package com.heatonresearch.examples.collections;
public class TestQueue {
public static void main(String args[]) {
Queue<Integer> queue = new Queue<Integer>();
queue.push(1);
queue.push(2);
queue.push(3);
try {
System.out.println("Pop 1:" + queue.pop());
System.out.println("Pop 2:" + queue.pop());
System.out.println("Pop 3:" + queue.pop());
}
catch (QueueException e) { e.printStackTrace(); }
}
}
前面的代碼中創建的隊列僅接收整型對象。
Queue<Integer> queue = new Queue<Integer>();
接下來的測試把三個整數添加到該隊列上。
queue.push(1);
queue.push(2);
queue.push(3);
注意,添加到該隊列中的這些數字都是原始的類型。因為J2SE的自動裝箱特性,這些原始的int類型被自動地轉變成Integer對象。
接下來,該測試使用pop方法檢索對象。在該隊列為空的情況下,該測試捕獲到QueueException異常。從隊列中彈出三個數字的結果是:
1
2
3
盡管在這裡作為一接收的整數隊列顯示,但是因為泛型,所以隊列類對於任何Java對象情況都能正常工作。
四、創建一個可預知的Stack集合
這裡是一個更復雜的集合類型-它實現了一個堆棧以使你在實際刪除一個對象之前能夠預知或"可偷看"。你可以或者通過使用一個迭代算子或使用J2SE 5.0的新的"for each"結構語句來進行預知。
這個PeekableStack類是一個先進後出(FILO)棧-讓你遍歷當前棧中的內容。它的實現使用了兩個類。首先,PeekableStack類實現實際的棧部分。其次,PeekableStackIterator類實現一個"Java標准的"Iterator類-你可以用它來遍歷整個棧。列表2(見所附源代碼文件)顯示出PeekableStack類的具體編碼。
注意,列表2中的PeekableStack類實現了Iterable接口。這對於支持新型的J2SE 5.0"for-each"結構語句是必要的。該Iterable接口用於指定你的集合支持"iterator"方法-它返回一個迭代算子。如果沒有這個接口,你的類將無法與新型的"for-each"結構語句相兼容。
這個可預知的棧包含push和pop方法,就象隊列一樣。該push方法僅僅是比隊列稍微復雜些。而push方法負責把對象添加到棧上去並增加版本數(version)。
這個version變量允許PeekableStackIterator類保證沒有修改操作發生。在迭代算子創建時,這個算子保留一份當前版本數。如果棧上通過調用push方法發生任何變化,那麼這個版本數就不會匹配;此不匹配將導致算子拋出一個ConcurrentModificationException異常。
pop方法稍微復雜些。首先,它必須決定在該列表中的最後一個元素,這是通過獲得列表的大小並且減去1而得到的。
int last = list.size() - 1;
如果這個結果是一個小於零的數字,那麼該棧就是空的,因此pop方法就返回null。
if (last < 0) return null;
如果在棧中存在最後一個元素,那麼就從列表中檢索它。在從列表中成功地檢索這個項後,你可以把它刪除。
T result = list.get(last);
list.remove(last);
最後,返回從列表中檢索的對象。
return result;
為支持"for each"迭代,PeekableStack類的iterator方法返回一個"Java標准的"Iterator類-你可以用它來遍歷包含在棧中的所有對象。iterator方法創建一個新的iterator並且返回之。
PeekableStackIterator peekableStackIterator=new
PeekableStackIterator(this, list);
如你所見,該iterator類接收當前棧和棧的項目列表作為構造器參數。這些值將為PeekableStackIterator所用-下一節將討論之。