1. 程式人生 > >【小家java】Java中Apache Commons-Collections4使用精講(對JDK集合功能的強有力擴充套件)

【小家java】Java中Apache Commons-Collections4使用精講(對JDK集合功能的強有力擴充套件)

相關閱讀

前言

雖然JDK提供給我們的集合框架已經足夠強大,基本能解決我們平時的絕大所述問題,並且效率還挺高。

本文針對於Apache提供的Collections4元件提供的一些特殊資料結構,通過例子解決一些實際問題的講解。

® bag介面
® 固定大小的map、lru (最近最少使用演算法)map和雙重(dual)map
® 物件陣列和map的迭代器
® map的multikey
® 大量的工具類,提供了使用api的快捷方式
® 封裝器,對大多數類提供了自定義的方法

Bag

Bag繼承自Collection介面,定義了一個集合,該集合會記錄物件在集合中出現的次數。

假設你有一個包,包含{a, a, b, c}。呼叫getCount(a)方法將返回2,呼叫uniqueset()方法將返回{a, b, c}的set集合。

public interface Bag<E> extends Collection<E> {}

顧名思義,它是包的意思,所以也是拿來裝資料的。

HashBag

HashBag使用HashMap作為資料儲存,是一個標準的Bag實現。

    public static void main(String[] args) {
        Bag hashBag = new HashBag();
        String s1 = "s1";
        String s2 = "s2";
        hashBag.add(s1);
        hashBag.
add(s1); //一次性放置多個元素 hashBag.add(s2, 3); // 獲得包中元素迭代器 Iterator<?> iterator = hashBag.iterator(); System.out.println("包中元素為:"); while (iterator.hasNext()) { System.out.println(iterator.next()); } System.out.println("包中元素個數為:"
+ hashBag.size()); //5 //下面兩個特有的方法 使用起來較為方便 System.out.println("包中entity1個數為:" + hashBag.getCount(s1)); //2 System.out.println("去重後個數為:" + hashBag.uniqueSet().size()); //2 } 結果輸出: 包中元素為: s1 s1 s2 s2 s2 包中元素個數為:5 包中entity1個數為:2 去重後個數為:2
TreeBag

TreeBag使用TreeMap作為資料儲存,用法與HashBag類似,只是TreeBag會使用自然順序對元素進行排序。

總結

使用的方式和List差不多,效果也大同小異。
場景:比如我們需要具體知道每個元素出現的次數的時候,並且實現快速去重,使用Bag會非常便捷

對應的BagUtils,能提供BagUtils.EMPTY_BAG、synchronizedBag、unmodifiableBag等程式設計同步、只讀的快捷方法

BidiMap: 雙重Map

使用雙向對映,可以使用值查詢鍵,並且可以使用鍵輕鬆查詢值。(自然,它可以根絕key移除,也可以根據value移除)

該場景使用還是比較多的,比如一對一的對映關係,都可以使用這來儲存。如果你使用HashMap,那你得維護兩個,還是比較麻煩的

public interface BidiMap<K, V> extends IterableMap<K, V> {}

也是個普通的Map。繼承IterableMap增加了一種迭代方式,例子裡會有講解

DualHashBidiMap

底層維護兩個HashMap,一個正向,一個逆向來達到效果的。

    public DualHashBidiMap() {
        super(new HashMap<K, V>(), new HashMap<V, K>());
    }
	//把一個普通的Map轉成BidiMap
    public DualHashBidiMap(final Map<? extends K, ? extends V> map) {
        super(new HashMap<K, V>(), new HashMap<V, K>());
        putAll(map);
    }

看個示例:

    public static void main(String[] args) {
        BidiMap<String, String> map = new DualHashBidiMap<>();
        map.put("key1", "value1");
        map.put("key2", "value2");
        map.put("key3", "value3");

        //多出來的一種遍歷方式  還是分廠人性化的
        MapIterator<String, String> it = map.mapIterator();
        while (it.hasNext()) {
            it.next(); //此句話必須呼叫  返回的是key,效果同getKey,但必須呼叫
            System.out.println(it.getKey() + "---" + it.getValue());
        }

        System.out.println(map.get("key1")); //value1
        //根據value拿key
        System.out.println(map.getKey("value1")); //key1
        //這個方法是Map介面的
        System.out.println(map.getOrDefault("k", "defaultValue")); //defaultValue
        //返回一個逆序的檢視  注意是檢視
        BidiMap<String, String> inverseMap = map.inverseBidiMap();

        //根據key刪除
        inverseMap.remove("key1");
        //根據value刪除
        inverseMap.removeValue("value2");

        System.out.println(map); //{key1=value1, key2=value2, key3=value3}
        System.out.println(inverseMap); //{value2=key2, value1=key1, value3=key3}
    }
輸出:
key1---value1
key2---value2
key3---value3
value1
key1
defaultValue
{key1=value1, key2=value2, key3=value3}
{value2=key2, value1=key1, value3=key3}
DualLinkedHashBidiMap

底層採用兩個LinkedHashMap儲存,其餘同上

DualTreeBidiMap

底層採用兩個TreeMap儲存,其餘同上

它不要求key和value都是實現了比較器介面的,但是自己可以自定義比較器介面傳進去

TreeBidiMap

注意TreeBidiMap和DualTreeBidiMap的區別
TreeBidiMap採用是紅黑樹:Node。一個node就是put的一個鍵值對,這樣子來實現雙端的Map,底層的原理和上面的不一樣。這樣的好處:可以最大程度的節約儲存空間,從而提高效率。

firstKey、lastKey、nextKey等等都有一套自己的實現,處理效率還是蠻高的

備註:使用起來基本同上,因此例項省略

此Map要求key和value必須必須必須都實現了比較器介面