J2ME 無標準緩存工具。SimpleCache 以 Hashtable + 雙向鏈表 實現 **O(1) 獲取/放入**、**LRU 淘汰**、**固定容量上限**,代碼 < 80 行,零依賴,適合圖片緩存、網絡響應緩存、RMS 熱數據緩存。
class Entry {
Object key, value;
Entry prev, next; // 雙向鏈表指針
Entry(Object k, Object v) { key = k; value = v; }
}
Hashtable cacheMap:Key → Entry (O(1) 查找)。Entry head, tail:虛擬頭尾節點,構建 LRU 雙向鏈表。int capacity:最大條目數。
public class SimpleCache {
private Hashtable cacheMap = new Hashtable();
private Entry head = new Entry(null, null), tail = new Entry(null, null);
private int capacity;
public SimpleCache(int capacity) {
this.capacity = capacity;
head.next = tail; tail.prev = head;
}
// 獲取並標記為最近使用
public Object get(Object key) {
Entry e = (Entry) cacheMap.get(key);
if (e == null) return null;
moveToHead(e);
return e.value;
}
// 放入或更新
public void put(Object key, Object value) {
Entry e = (Entry) cacheMap.get(key);
if (e != null) {
e.value = value;
moveToHead(e);
} else {
e = new Entry(key, value);
cacheMap.put(key, e);
addToHead(e);
if (cacheMap.size() > capacity) {
removeLRU();
}
}
}
// 移除指定鍵
public void remove(Object key) {
Entry e = (Entry) cacheMap.remove(key);
if (e != null) unlink(e);
}
// 核心鏈表操作
private void addToHead(Entry e) {
e.next = head.next; e.prev = head;
head.next.prev = e; head.next = e;
}
private void unlink(Entry e) {
e.prev.next = e.next; e.next.prev = e.prev;
}
private void moveToHead(Entry e) {
unlink(e); addToHead(e);
}
private void removeLRU() {
Entry lru = tail.prev;
unlink(lru);
cacheMap.remove(lru.key);
}
}
// 容量 20 張圖片
SimpleCache imageCache = new SimpleCache(20);
// 獲取圖片
Image img = (Image) imageCache.get("/res/bg.png");
if (img == null) {
img = loadImage("/res/bg.png"); // 真實加載
imageCache.put("/res/bg.png", img);
}
g.drawImage(img, x, y, Graphics.TOP | Graphics.LEFT);
Object,調用方轉型。synchronized(cache) 或內部加 synchronized (微增開銷)。value 改為 WeakReference (需 CLDC 1.1/外部庫),get() 時檢查 ref.get() != null。hitCount/missCount 監控命中率。SimpleCache 以經典 HashMap + 雙向鏈表 結構,在 J2ME 受限環境下提供生產級 LRU 緩存能力。理解其核心不變量 (head.next=MRU, tail.prev=LRU),即可靈活擴展 TTLR、分級緩存、預熱策略等高級功能。