Skip to main content
 首页 » 编程设计

Apache Commons Collections Bag 教程

2022年07月19日142qq78292959

本文带你了解 Apache Commons Collections Bag,它允许多次存储相同元素。

Bag 与 Collection的差异

首先,我们加入maven依赖,然后通过示例进行说明:

<dependency> 
    <groupId>org.apache.commons</groupId> 
    <artifactId>commons-collections4</artifactId> 
    <version>4.1</version> 
</dependency> 

下面示例插入重复元素,并验证1的个数是否为2个:

public void whenAdded_thenCountIsKept() {
    
    Bag<Integer> bag = new HashBag<>( 
      Arrays.asList(1, 2, 3, 3, 3, 1, 4)); 
         
    assertThat(2, equalTo(bag.getCount(1))); 
} 
  • 违法Collection约定

查看 Bag API 文档,我们注意到一些方法标记为违反了Collection的约定。举例,Java Collection的add方法,如果增加已经存在的元素返回true:

Collection<Integer> collection = new ArrayList<>(); 
collection.add(1); 
assertThat(collection.add(1), is(true)); 

但Bag 相同add API 返回false:

Bag<Integer> bag = new HashBag<>(); 
bag.add(1); 
  
assertThat(bag.add(1), is(not(true))); 

为了保持兼容,Apache Collections提供了包装器CollectionBag ,使用它可以保持接口兼容:

public void whenBagAddAPILikeCollectionAPI_thenTrue() {
    
    Bag<Integer> bag = CollectionBag.collectionBag(new HashBag<>()); 
    bag.add(1); 
 
    assertThat(bag.add(1), is((true))); 
} 

Bag实现

下面我们看看Apache collection 库中Bag接口的不同实现。

HashBag

我们可以增加元素,并告诉API该元素的重复次数:

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); // 删除1个3元素, 仍有2个3元素 
    assertThat(2, equalTo(bag.getCount(3))); 
	 
    bag.remove(1); // 删除所有1元素 
    assertThat(0, equalTo(bag.getCount(1))); 
} 

TreeBag

TreeBag 实现与其他tree一样,并增加了Bag接口语义。可以按照自然顺序进行排序,下面是整型元素的示例:

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 Collection规范:

public void whenTreeAddAPILikeCollectionAPI_thenTrue() {
    
    SortedBag<Integer> bag  = CollectionSortedBag.collectionSortedBag(new TreeBag<>()); 
 
    bag.add(1); 
    assertThat(bag.add(1), is((true))); 
} 

SynchronizedSortedBag

另一个广泛使用的Bag实现是SynchronizedSortedBag,准确地说,这是SortedBag实现增加了同步装饰器。我们可以使用该装饰器包装TreeBag:

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)); 
} 

我们可以合并Collections.synchronizedSortedMap() 和TreeMap API模拟上面示例使用SynchronizedSortedBag实现的功能。

总结

本文学习Bag接口以及其不同实现。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/120503846
阅读延展