Apache Commons包
1.簡介
在這篇快速文章中,我們將重點介紹如何使用Apache的Bag集合。
2. Maven依賴
在開始之前,我們需要從Maven Central導入最新的依賴項:
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.1</version>
</dependency>
3.手提袋與收藏
簡而言之, Bag是一個集合,可以存儲多個項目及其重複計數:
public void whenAdded_thenCountIsKept() {
Bag<Integer> bag = new HashBag<>(
Arrays.asList(1, 2, 3, 3, 3, 1, 4));
assertThat(2, equalTo(bag.getCount(1)));
}
3.1 違反Collection條約
在閱讀Bag的API文檔時,我們可能會注意到某些方法被標記為違反了標準Java的Collection條約。
例如,當我們使用Java集合中的*add()
* API時,即使該項目已經在集合中,我們也會收到true :
Collection<Integer> collection = new ArrayList<>();
collection.add(1);
assertThat(collection.add(1), is(true));
當我們添加集合中已經可用的元素時,來自Bag實現的相同API將返回false 。
Bag<Integer> bag = new HashBag<>();
bag.add(1);
assertThat(bag.add(1), is(not(true)));
為了解決這些問題,Apache Collections的庫提供了一個稱為CollectionBag的裝飾器。我們可以使用它來使我們的bag collection符合Java Collection合同:
public void whenBagAddAPILikeCollectionAPI_thenTrue() {
Bag<Integer> bag = CollectionBag.collectionBag(new HashBag<>());
bag.add(1);
assertThat(bag.add(1), is((true)));
}
4. Bag實現
現在,讓我們在Apache的collections庫中探索Bag接口的各種實現。
4.1 HashBag
我們可以添加一個元素,並指示API該元素在我們的bag集合中應具有的副本數:
public void givenAdd_whenCountOfElementsDefined_thenCountAreAdded() {
Bag<Integer> bag = new HashBag<>();
bag.add(1, 5); // adding 1 five times
assertThat(5, equalTo(bag.getCount(1)));
}
我們還可以從包中刪除特定數量的副本或元素的每個實例:
public void givenMultipleCopies_whenRemove_allAreRemoved() {
Bag<Integer> bag = new HashBag<>(
Arrays.asList(1, 2, 3, 3, 3, 1, 4));
bag.remove(3, 1); // remove one element, two still remain
assertThat(2, equalTo(bag.getCount(3)));
bag.remove(1); // remove all
assertThat(0, equalTo(bag.getCount(1)));
}
4.2 TreeBag
TreeBag實現的工作方式與其他任何樹一樣,另外還保留了Bag語義。
我們自然可以使用TreeBag對整數數組進行排序,然後查詢集合中每個單個元素具有的實例數:
public void givenTree_whenDuplicateElementsAdded_thenSort() {
TreeBag<Integer> bag = new TreeBag<>(Arrays.asList(7, 5,
1, 7, 2, 3, 3, 3, 1, 4, 7));
assertThat(bag.first(), equalTo(1));
assertThat(bag.getCount(bag.first()), equalTo(2));
assertThat(bag.last(), equalTo(7));
assertThat(bag.getCount(bag.last()), equalTo(3));
}
TreeBag實現了SortedBag接口,此接口的所有實現都可以使用裝飾器CollectionSortedBag來遵守Java Collections協定:
public void whenTreeAddAPILikeCollectionAPI_thenTrue() {
SortedBag<Integer> bag
= CollectionSortedBag.collectionSortedBag(new TreeBag<>());
bag.add(1);
assertThat(bag.add(1), is((true)));
}
4.3 SynchronizedSortedBag
Bag的另一個廣泛使用的實現是SynchronizedSortedBag 。確切地說,這是SortedBag實現的同步裝飾器。
我們可以使用這個裝飾與我們從上一節同步訪問我們的袋子TreeBag(SortedBag的實現):
public void givenSortedBag_whenDuplicateElementsAdded_thenSort() {
SynchronizedSortedBag<Integer> bag = SynchronizedSortedBag
.synchronizedSortedBag(new TreeBag<>(
Arrays.asList(7, 5, 1, 7, 2, 3, 3, 3, 1, 4, 7)));
assertThat(bag.first(), equalTo(1));
assertThat(bag.getCount(bag.first()), equalTo(2));
assertThat(bag.last(), equalTo(7));
assertThat(bag.getCount(bag.last()), equalTo(3));
}
我們可以結合使用API( Collections.synchronizedSortedMap()
和TreeMap
)的組合來模擬我們在SynchronizedSortedBag中所做的事情。
5.結論
在這個簡短的教程中,我們了解了Bag接口及其各種實現。
與往常一樣,可以在GitHub上找到本文的代碼。
下一個 »
Apache Commons Collections SetUtils