Apache Commons Collections MapUtils

Apache Commons Collections MapUtils

1. 前書き

MapUtilsは、Apache CommonsCollectionsプロジェクトで使用できるツールの1つです。

簡単に言えば、java.util.Mapおよびjava.util.SortedMapインスタンスを操作するためのユーティリティメソッドとデコレータを提供します。

2. セットアップ

the dependencyを追加することから始めましょう:


    org.apache.commons
    commons-collections4
    4.1

3. 効用メソッド

3.1. ArrayからMapを作成する

それでは、マップの作成に使用する配列を設定しましょう。

public class MapUtilsTest {
    private String[][] color2DArray = new String[][] {
        {"RED", "#FF0000"},
        {"GREEN", "#00FF00"},
        {"BLUE", "#0000FF"}
    };
    private String[] color1DArray = new String[] {
        "RED", "#FF0000",
        "GREEN", "#00FF00",
        "BLUE", "#0000FF"
    };
    private Map colorMap;

    //...
}

2次元配列からマップを作成する方法を見てみましょう。

@Test
public void whenCreateMapFrom2DArray_theMapIsCreated() {
    this.colorMap = MapUtils.putAll(
      new HashMap<>(), this.color2DArray);

    assertThat(
      this.colorMap,
      is(aMapWithSize(this.color2DArray.length)));

    assertThat(this.colorMap, hasEntry("RED", "#FF0000"));
    assertThat(this.colorMap, hasEntry("GREEN", "#00FF00"));
    assertThat(this.colorMap, hasEntry("BLUE", "#0000FF"));
}

1次元配列を使用することもできます。 その場合、配列は代替インデックスのキーと値として扱われます。

@Test
public void whenCreateMapFrom1DArray_theMapIsCreated() {
    this.colorMap = MapUtils.putAll(
      new HashMap<>(), this.color1DArray);

    assertThat(
      this.colorMap,
      is(aMapWithSize(this.color1DArray.length / 2)));

    assertThat(this.colorMap, hasEntry("RED", "#FF0000"));
    assertThat(this.colorMap, hasEntry("GREEN", "#00FF00"));
    assertThat(this.colorMap, hasEntry("BLUE", "#0000FF"));
}

3.2. Mapのコンテンツの印刷

デバッグ中またはデバッグログで何度も、マップ全体を出力したいと思います。

@Test
public void whenVerbosePrintMap_thenMustPrintFormattedMap() {
    MapUtils.verbosePrint(System.out, "Optional Label", this.colorMap);
}

そしてその結果:

Optional Label =
{
    RED = #FF0000
    BLUE = #0000FF
    GREEN = #00FF00
}

値のデータ型を追加で出力するdebugPrint()を使用することもできます。

3.3. 値の取得

MapUtilsは、nullで安全な方法で、特定のキーのマップから値を抽出するためのいくつかのメソッドを提供します。

たとえば、getString()MapからStringを取得します。 String値は、toString()を介して取得されます。 オプションで、値がnullの場合、または変換が失敗した場合に返されるデフォルト値を指定できます。

@Test
public void whenGetKeyNotPresent_thenMustReturnDefaultValue() {
    String defaultColorStr = "COLOR_NOT_FOUND";
    String color = MapUtils
      .getString(this.colorMap, "BLACK", defaultColorStr);

    assertEquals(color, defaultColorStr);
}

これらのメソッドはnull-safeであることに注意してください。 nullマップパラメータを安全に処理できます。

@Test
public void whenGetOnNullMap_thenMustReturnDefaultValue() {
    String defaultColorStr = "COLOR_NOT_FOUND";
    String color = MapUtils.getString(null, "RED", defaultColorStr);

    assertEquals(color, defaultColorStr);
}

ここで、マップがnullであっても、colorは値をCOLOR_NOT_FOUNDとして取得します。

3.4. Mapを反転する

マップを簡単に逆にすることもできます。

@Test
public void whenInvertMap_thenMustReturnInvertedMap() {
    Map invColorMap = MapUtils.invertMap(this.colorMap);

    int size = invColorMap.size();
    Assertions.assertThat(invColorMap)
      .hasSameSizeAs(colorMap)
      .containsKeys(this.colorMap.values().toArray(new String[] {}))
      .containsValues(this.colorMap.keySet().toArray(new String[] {}));
}

これにより、colorMap:に反転します

{
    #00FF00 = GREEN
    #FF0000 = RED
    #0000FF = BLUE
}

ソースマップが複数のキーに同じ値を関連付けている場合、反転後、値の1つがランダムにキーになります。

3.5. ヌルチェックと空チェック

Mapnullであるか空の場合、isEmpty()メソッドはtrueを返します。

safeAddToMap()メソッドは、Map.へのnull要素の追加を防ぎます

4. デコレータ

これらのメソッドは、Map.に機能を追加します

ほとんどの場合、装飾されたMap.への参照を保存しないことをお勧めします

4.1. 固定サイズMap

fixedSizeMap()は、指定されたマップに裏打ちされた固定サイズのマップを返します。 要素は変更できますが、追加または削除することはできません。

@Test(expected = IllegalArgumentException.class)
public void whenCreateFixedSizedMapAndAdd_thenMustThrowException() {
    Map rgbMap = MapUtils
      .fixedSizeMap(MapUtils.putAll(new HashMap<>(), this.color1DArray));

    rgbMap.put("ORANGE", "#FFA500");
}

4.2. 述語Map

predicatedMap()メソッドはMapを返し、保持されているすべての要素が指定された述語と一致することを保証します。

@Test(expected = IllegalArgumentException.class)
public void whenAddDuplicate_thenThrowException() {
    Map uniqValuesMap
      = MapUtils.predicatedMap(this.colorMap, null,
        PredicateUtils.uniquePredicate());

    uniqValuesMap.put("NEW_RED", "#FF0000");
}

ここでは、PredicateUtils.uniquePredicate()を使用して値の述語を指定しました。 このマップに重複する値を挿入しようとすると、java.lang.IllegalArgumentExceptionになります。

Predicateインターフェースを実装することにより、カスタム述語を実装できます。

4.3. 怠惰なMap

lazyMap()は、要求されたときに値が初期化されるマップを返します。

このマップのMap.get(Object)メソッドに渡されたキーがマップに存在しない場合、Transformerインスタンスは、要求されたキーに関連付けられる新しいオブジェクトを作成するために使用されます。

@Test
public void whenCreateLazyMap_theMapIsCreated() {
    Map intStrMap = MapUtils.lazyMap(
      new HashMap<>(),
      TransformerUtils.stringValueTransformer());

    assertThat(intStrMap, is(anEmptyMap()));

    intStrMap.get(1);
    intStrMap.get(2);
    intStrMap.get(3);

    assertThat(intStrMap, is(aMapWithSize(3)));
}

5. 結論

このクイックチュートリアルでは、Apache Commons CollectionsのMapUtilsクラスについて説明し、さまざまな一般的なマップ操作を簡素化できるさまざまなユーティリティメソッドとデコレータについて説明しました。

いつものように、コードはover on GitHubで利用できます。