Commons Collections Bag 介面擴充 Collection,增加元素計數語義。本文解析 Bag/SortedBag 介面契約、基礎實作 DefaultMapBag 核心邏輯、具體實作 HashBag/TreeBag、以及工具類 BagUtils 提供的裝飾器組合式 API。
public interface Bag extends Collection {
int getCount(Object object); // 取得元素出現次數
boolean add(Object object); // 加入單一元素
boolean add(Object object, int nCopies); // 批量加入
boolean remove(Object object); // 移除單一
boolean remove(Object object, int nCopies); // 批量移除
Set uniqueSet(); // 不重複元素集合視圖
// 繼承: size(), iterator(), containsAll()...
}
public interface SortedBag extends Bag {
Comparator comparator();
Object first(); // 最小元素
Object last(); // 最大元素
}
以 Map<Object, Integer> 為底層存儲,_total 記錄總元素數,_mods 實作快速失效迭代器。
public abstract class DefaultMapBag implements Bag {
private Map _map; private int _total; private int _mods;
public boolean add(Object object, int nCopies) {
_mods++;
if (nCopies > 0) {
int count = nCopies + getCount(object);
_map.put(object, new Integer(count));
_total += nCopies;
return (count == nCopies); // true = 新元素
}
return false;
}
public boolean remove(Object object, int nCopies) {
_mods++;
int count = getCount(object);
if (nCopies <= 0) return false;
if (count > nCopies) {
_map.put(object, new Integer(count - nCopies));
_total -= nCopies; return true;
} else if (count > 0) {
_total -= count;
return (_map.remove(object) != null);
}
return false;
}
// containsAll/retainAll/equals/hashCode/toString/iterator 完整實作...
private List extractList() { // 將計數展開為 List
List result = new ArrayList();
for (Object o : uniqueSet()) for (int i=getCount(o); i>0; i--) result.add(o);
return result;
}
protected static class BagIterator implements Iterator { ... } // 快速失效
}
Integer 包裝,每次修改建立新物件(較 MutableInteger 效能稍遜,但簡單)。extractList() 將 Bag 攤平成 List,供 toArray()/iterator() 使用。uniqueSet() 回傳 UnmodifiableSet.decorate(_map.keySet())。| 類別 | 建構子 | 底層 Map |
|---|---|---|
HashBag | HashBag() / HashBag(Collection) | new HashMap() |
TreeBag | TreeBag() / TreeBag(Comparator) / TreeBag(Collection) | new TreeMap() / new TreeMap(Comparator) |