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