J2SE 5.0 引入泛型,允許類別定義型別參數:
public class Example<ONE, TWO, THREE> {
private ONE one; private TWO two; private THREE three;
// getter/setter...
}
// 使用時具體化型別
Example<Double, Integer, String> ex = new Example<>();
ex.setOne(1.5); ex.setTwo(2); ex.setThree("Three");
關鍵點:型別擦除僅存在編譯期,執行期為原始類型;但編譯器提供型別安全保證。
public class Queue<T> {
private List<T> list = new ArrayList<>();
public void push(T obj) { list.add(obj); }
public T pop() throws QueueException {
if (list.isEmpty())
throw new QueueException("Queue is empty");
T result = list.remove(0);
return result;
}
public boolean isEmpty() { return list.isEmpty(); }
public int size() { return list.size(); }
public void clear() { list.clear(); }
}
// 自訂例外
public class QueueException extends Exception {
public QueueException(String msg) { super(msg); }
}
// 測試
Queue<Integer> q = new Queue<>();
q.push(1); q.push(2); q.push(3); // 自動裝箱 int → Integer
System.out.println(q.pop()); // 1
System.out.println(q.pop()); // 2
System.out.println(q.pop()); // 3
public class PeekableStack<T> implements Iterable<T> {
private List<T> list = new ArrayList<>();
private int version = 0; // 版本號偵測並發修改
public void push(T obj) {
list.add(obj);
version++;
}
public T pop() {
if (list.isEmpty()) return null;
version++;
return list.remove(list.size() - 1);
}
public T peek() {
return list.isEmpty() ? null : list.get(list.size() - 1);
}
@Override
public Iterator<T> iterator() {
return new PeekableStackIterator<>(this, new ArrayList<>(list), version);
}
// 內部類別:快照式迭代器
private static class PeekableStackIterator<T> implements Iterator<T> {
private final List<T> snapshot;
private final int expectedVersion;
private int index = 0;
PeekableStackIterator(PeekableStack<T> stack, List<T> snapshot, int version) {
this.snapshot = snapshot;
this.expectedVersion = version;
}
@Override
public boolean hasNext() { return index < snapshot.size(); }
@Override
public T next() {
// 可選:檢查並發修改
return snapshot.get(index++);
}
@Override
public void remove() { throw new UnsupportedOperationException(); }
}
}
| 決策點 | 方案 | 理由 |
|---|---|---|
| 迭代器實作 | 快照模式 (Snapshot) | 避免 ConcurrentModificationException、支援多迭代器並存 |
| 版本號機制 | push/pop 遞增 version | 可選擇性檢查:建構迭代器時記錄 version,next() 時比對 |
| 實作 Iterable | 而非 Iterator | 支援 for-each 語法:for (T item : stack) |
| 泛型傳播 | Iterator<T> 保持型別 | 編譯期型別安全、無需轉型 |
PeekableStack<Integer> stack = new PeekableStack<>();
stack.push(1); stack.push(2); stack.push(3);
// for-each 迭代(不修改堆疊)
for (int i : stack) {
System.out.println(i); // 輸出 1, 2, 3 (底部到頂部)
}
// 正常堆疊操作
System.out.println("Pop: " + stack.pop()); // 3
System.out.println("Pop: " + stack.pop()); // 2
System.out.println("Pop: " + stack.pop()); // 1
為無縫整合,建議額外實作:
Collection<T> 介面:獲得 addAll、containsAll 等標準操作Serializable:支援序列化Cloneable:支援淺層複製toArray() 方法Queue q = new Queue(),會失去型別檢查<? extends T> (生產者)、<? super T> (消費者)LinkedList、隨機存取用 ArrayList@param <T> 元素型別J2SE 5.0 泛型與 for-each 徹底改變集合開發體驗。實作自訂集合只需:
<T>List<T> 或 T[]Iterable<T> 支援 for-eachCollection<T> 獲得完整標準 API如此即可享受編譯期型別安全、程式碼可讀性與零轉型的現代 Java 集合開發體驗。