系列: Angelia
java
87 行
· 更新於 2026-09-27
ArrayGuestList.java
Angelia/Java/Week_6_7/code/06_generics_collections/ArrayGuestList.java
import java.util.Arrays;
/**
* 泛型版的「嚴格」陣列實作。
*
* 型別擦除(type erasure)的限制:執行期不知道 T 是什麼,所以「不能」寫 new T[n]。
* 標準做法:內部用 Object[] 存,取出時再轉型成 T。
* 只要我們靠封裝保證「陣列裡只放過 T」,這個「未受檢查的轉型」在實務上就是安全的。
*
* 資料不變量:data[0..used-1] 非 null 且互不相同(用 equals 比較)。
*/
public class ArrayGuestList<T> implements GuestList<T> {
private Object[] data = new Object[2]; // 不能是 T[]!
private int used = 0;
@Override
public void add(T guest) {
if (guest == null) {
throw new IllegalArgumentException("賓客不可為 null");
}
if (isComing(guest)) {
return;
}
if (this.used == this.data.length) {
this.data = Arrays.copyOf(this.data, this.used * 2); // 標準函式庫幫我們倍增+複製
}
this.data[this.used] = guest;
this.used = this.used + 1;
}
@Override
public void remove(T guest) {
int i = 0;
while (i < this.used) {
if (this.data[i].equals(guest)) {
// 用最後一個元素填補洞,保持 data[0..used-1] 沒有 null
this.data[i] = this.data[this.used - 1];
this.data[this.used - 1] = null;
this.used = this.used - 1;
return;
}
i = i + 1;
}
}
@Override
public boolean isComing(T guest) {
int i = 0;
while (i < this.used) {
if (this.data[i].equals(guest)) {
return true;
}
i = i + 1;
}
return false;
}
@Override
public int count() {
return this.used;
}
/**
* ★ 型別擦除的陷阱:這個陣列在執行期「真的」是 Object[]。
* 呼叫端若寫 String[] s = list.coming(); 會在執行期拋出 ClassCastException!
* (寫 Object[] s = list.coming(); 則沒問題。)見 Demo.java 的示範與 comingList() 的正解。
*/
@Override
@SuppressWarnings("unchecked") // 告訴編譯器:我知道這個轉型沒被檢查,我負責它的安全
public T[] coming() {
// Arrays.copyOf 回傳的是新陣列(防禦性複製);(T[]) 是「未受檢查的轉型」
return (T[]) Arrays.copyOf(this.data, this.used);
}
/** 正解:回傳 List<T>。泛型集合沒有陣列的執行期型別問題,這也是標準函式庫的做法。 */
@SuppressWarnings("unchecked")
public java.util.List<T> comingList() {
java.util.List<T> result = new java.util.ArrayList<>();
int i = 0;
while (i < this.used) {
result.add((T) this.data[i]); // 單一元素的轉型:執行期什麼都不檢查(T 已被擦除)
i = i + 1;
}
return result;
}
}
相關文章
Angelia
haskell
EN
更新於 2026-02-03
Adding.hs
Adding.hs — haskell source code from the Angelia learning materials (Angelia/Haskell/Adding.hs).
閱讀文章 →
Angelia
haskell
EN
更新於 2026-02-03
Area.hs
Area.hs — haskell source code from the Angelia learning materials (Angelia/Haskell/Area.hs).
閱讀文章 →
Angelia
haskell
EN
更新於 2026-02-03
Chess.hs
Chess.hs — haskell source code from the Angelia learning materials (Angelia/Haskell/Chess.hs).
閱讀文章 →
Angelia
haskell
EN
更新於 2026-02-03
ChessGraphics.hs
ChessGraphics.hs — haskell source code from the Angelia learning materials (Angelia/Haskell/ChessGraphics.hs).
閱讀文章 →
Angelia
haskell
EN
更新於 2026-02-03
Examples.hs
Examples.hs — haskell source code from the Angelia learning materials (Angelia/Haskell/Examples.hs).
閱讀文章 →
Angelia
haskell
EN
更新於 2026-02-03
Fibonacci.hs
Fibonacci.hs — haskell source code from the Angelia learning materials (Angelia/Haskell/Fibonacci.hs).
閱讀文章 →