【小家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必須必須必須都實現了比較器介面