Apache Commonsコレクションバッグ

Apache Commonsコレクションバッグ

1. 前書き

この簡単な記事では、ApacheのBagコレクションの使用方法に焦点を当てます。

参考文献:

Apache Commons BeanUtils

一般的なBean操作でのApache Commons BeanUtilsの使用方法を学習します。

Apache Commons IO

Java用のApache Commons IOオープンソースライブラリのよく知られた機能の多くをカバーする、迅速で実用的なガイド。

Apache Commons Textの概要

一般的な文字列操作にApache Commons Textを使用する方法を学びます。

2. メーベン依存

開始する前に、Maven Centralから最新の依存関係をインポートする必要があります。


    org.apache.commons
    commons-collections4
    4.1

3. バッグvsコレクション

簡単に言うと、Bagは、複数のアイテムとその繰り返し数を格納できるコレクションです。

public void whenAdded_thenCountIsKept() {
    Bag bag = new HashBag<>(
      Arrays.asList(1, 2, 3, 3, 3, 1, 4));

    assertThat(2, equalTo(bag.getCount(1)));
}

3.1. Collection契約の違反

BagのAPIドキュメントを読んでいると、一部のメソッドが標準のJavaのコレクションコントラクトに違反しているとマークされていることに気付く場合があります。

たとえば、Javaコレクションからadd() APIを使用すると、アイテムがすでにコレクションに含まれている場合でも、trueを受け取ります。

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

コレクションですでに使用可能な要素を追加すると、Bag実装の同じAPIがfalseを返します。

Bag bag = new HashBag<>();
bag.add(1);

assertThat(bag.add(1), is(not(true)));

これらの問題を解決するために、Apache CollectionsのライブラリはCollectionBag.と呼ばれるデコレータを提供します。これを使用して、バッグコレクションをJavaCollectionコントラクトに準拠させることができます。

public void whenBagAddAPILikeCollectionAPI_thenTrue() {
    Bag bag = CollectionBag.collectionBag(new HashBag<>());
    bag.add(1);

    assertThat(bag.add(1), is((true)));
}

4. バッグの実装

次に、Apacheのコレクションライブラリ内のBagインターフェイスのさまざまな実装について見ていきましょう。

4.1. HashBag

要素を追加し、この要素をバッグコレクションに含める必要があるコピーの数をAPIに指示できます。

public void givenAdd_whenCountOfElementsDefined_thenCountAreAdded() {
    Bag bag = new HashBag<>();

    bag.add(1, 5); // adding 1 five times

    assertThat(5, equalTo(bag.getCount(1)));
}

バッグから特定の数のコピーまたは要素のすべてのインスタンスを削除することもできます。

public void givenMultipleCopies_whenRemove_allAreRemoved() {
    Bag 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 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));
}

TreeBagSortedBagインターフェースを実装します。このインターフェースのすべての実装は、デコレータCollectionSortedBagを使用してJavaコレクションコントラクトに準拠できます。

public void whenTreeAddAPILikeCollectionAPI_thenTrue() {
    SortedBag bag
      = CollectionSortedBag.collectionSortedBag(new TreeBag<>());

    bag.add(1);

    assertThat(bag.add(1), is((true)));
}

4.3. SynchronizedSortedBag

Bagのもう1つの広く使用されている実装は、SynchronizedSortedBagです。 正確には、これはSortedBag実装の同期デコレータです。

このデコレータを前のセクションのTreeBagSortedBagの実装)とともに使用して、バッグへのアクセスを同期できます。

public void givenSortedBag_whenDuplicateElementsAdded_thenSort() {
    SynchronizedSortedBag 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インターフェースとそのさまざまな実装について学習しました。

いつものように、この記事のコードはover on GitHubにあります。