首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Commons Collections 學習筆記(二):Bag 介面與實作全家族解析

     編輯:Java 相關知識

Bag(多重集合)允許重複元素並記錄每個元素的出現次數。Commons Collections 提供完整的 Bag 體系:核心介面、抽象基礎實作、具體實作(HashBag/TreeBag)、裝飾器模式擴充(同步、唯讀、謂詞過濾、型別檢查),本文系統梳理全家族類別結構與核心邏輯。

核心介面體系

public interface Bag extends Collection {
    int getCount(Object object);
    boolean add(Object object, int nCopies);
    boolean remove(Object object, int nCopies);
    Set uniqueSet(); // 不重複元素視圖
    // 繼承 Collection: size(), iterator(), containsAll()...
}

public interface SortedBag extends Bag {
    Comparator comparator();
    Object first(); // 最小元素
    Object last();  // 最大元素
}

抽象基礎實作:AbstractMapBag

以 Map<Object, MutableInteger> 為底層存儲,MutableInteger 封裝可變計數器。

public abstract class AbstractMapBag implements Bag {
    private transient Map map; private int size; private transient int modCount;
    private transient Set uniqueSet;

    public int getCount(Object object) {
        MutableInteger c = (MutableInteger) map.get(object);
        return (c != null) ? c.value : 0;
    }
    public boolean add(Object object, int nCopies) {
        if (nCopies <= 0) return false;
        modCount++; size += nCopies;
        MutableInteger c = (MutableInteger) map.get(object);
        if (c == null) { map.put(object, new MutableInteger(nCopies)); return true; }
        c.value += nCopies; return false;
    }
    // remove/removeAll/retainAll/iterator/序列化/equals/hashCode/toString 完整實作...
    protected static class MutableInteger { int value; ... }
}
  • MutableInteger 避免頻繁建立新 Integer 物件,提升高頻計數效能。
  • BagIterator 內部類實作疊代器,支援 remove() 正確遞減計數。
  • uniqueSet() 回傳 UnmodifiableSet.decorate(map.keySet())。

具體實作類別

兩者皆提供無參、Comparator、Collection 建構子,並正確處理序列化(TreeBag 需額外序列化 Comparator)。

裝飾器模式擴充體系

所有裝飾器繼承 AbstractBagDecorator / AbstractSortedBagDecorator,委派給被裝飾 Bag。

類別底層 Map特性
HashBagHashMap無序、O(1) 存取、可序列化
TreeBagTreeMap有序、實作 SortedBag、支援 first()/last()/comparator()

SortedBag 對應 SynchronizedSortedBag、UnmodifiableSortedBag、PredicatedSortedBag、TypedSortedBag、TransformedSortedBag。

BagUtils 統一入口

public class BagUtils {
    public static final Bag EMPTY_BAG = UnmodifiableBag.decorate(new HashBag());
    public static final Bag EMPTY_SORTED_BAG = UnmodifiableSortedBag.decorate(new TreeBag());

    public static Bag synchronizedBag(Bag bag) { return SynchronizedBag.decorate(bag); }
    public static Bag unmodifiableBag(Bag bag) { return UnmodifiableBag.decorate(bag); }
    public static Bag predicatedBag(Bag bag, Predicate p) { return PredicatedBag.decorate(bag, p); }
    public static Bag typedBag(Bag bag, Class type) { return TypedBag.decorate(bag, type); }
    public static Bag transformedBag(Bag bag, Transformer t) { return TransformedBag.decorate(bag, t); }
    // SortedBag 版本對應...
}

使用範例

Bag bag = new HashBag();
bag.add("apple", 3);
bag.add("banana", 2);
System.out.println(bag.getCount("apple")); // 3
System.out.println(bag.uniqueSet()); // [apple, banana]

// 型別安全 + 唯讀 + 執行緒安全
Bag safeBag = BagUtils.unmodifiableBag(
    BagUtils.typedBag(
        BagUtils.synchronizedBag(new HashBag()), String.class));
safeBag.add("orange"); // OK
// safeBag.add(123); // ClassCastException

設計亮點總結

  1. Map + 可變計數器:以 Map 統一存儲,MutableInteger 解決 Integer 不可變導致的頻繁物件創建。
  2. 裝飾器組合:單一職責原則,功能正交組合(同步+型別+唯讀),避免類別爆炸。
  3. 介面分層:Bag / SortedBag 清楚分離有序與無序語義。
  4. 標準 Collection 相容:實作 Collection 介面,可無縫接入標準 API。

結語

Commons Collections Bag 體系展示了經典集合擴充設計:核心介面清晰、基礎實作高效、裝飾器組合靈活。掌握 AbstractMapBag 計數器模式與 BagUtils 組合式 API,能在需要「重複元素計數」、「型別安全」、「執行緒安全」等複合需求時快速構建健壯解決方案。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
裝飾器功能靜態工廠方法
SynchronizedBag執行緒安全包裝BagUtils.synchronizedBag()
UnmodifiableBag唯讀檢視BagUtils.unmodifiableBag()
PredicatedBag元素謂詞驗證(加入前檢查)BagUtils.predicatedBag()
TypedBag型別檢查(InstanceofPredicate)BagUtils.typedBag()
TransformedBag元素轉換(加入時自動轉型)BagUtils.transformedBag()