グアバレンジセットガイド

グアバレンジセットガイド

1. 概要

このチュートリアルでは、Google GuavaのRangeSetインターフェースとその実装の使用方法を示します。

RangeSetは、0個以上の空でない切断された範囲で構成されるセットです。 可変RangeSetに範囲を追加すると、接続されている範囲はすべてマージされ、空の範囲は無視されます。

RangeSetの基本的な実装はTreeRangeSetです。

2. Google GuavaのRangeSet

RangeSetクラスの使用方法を見てみましょう。

2.1. メーベン依存

pom.xmlにGoogleのGuavaライブラリの依存関係を追加することから始めましょう。


    com.google.guava
    guava
    21.0

依存関係の最新バージョンはhereで確認できます。

3. 作成

RangeSetのインスタンスを作成するいくつかの方法を見てみましょう。

まず、クラスTreeRangeSetcreateメソッドを使用して、可変セットを作成できます。

RangeSet numberRangeSet = TreeRangeSet.create();

すでにコレクションが配置されている場合は、クラスTreeRangeSetcreateメソッドを使用して、そのコレクションを渡すことで可変セットを作成します。

List> numberList = Arrays.asList(Range.closed(0, 2));
RangeSet numberRangeSet = TreeRangeSet.create(numberList);

最後に、不変の範囲セットを作成する必要がある場合は、ImmutableRangeSetクラスを使用します(ビルダーパターンに従って作成します)。

RangeSet numberRangeSet
  = new ImmutableRangeSet.builder().add(Range.closed(0, 2)).build();

4. 使用法

RangeSetの使用法を示す簡単な例から始めましょう。

4.1. 範囲への追加

提供された入力が、セット内の範囲項目のいずれかに存在する範囲内にあるかどうかを確認できます。

@Test
public void givenRangeSet_whenQueryWithinRange_returnsSucessfully() {
    RangeSet numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 5));
    numberRangeSet.add(Range.closed(6, 8));

    assertTrue(numberRangeSet.contains(1));
    assertFalse(numberRangeSet.contains(9));
}

ノート:

  • Rangeクラスのclosedメソッドは、整数値の範囲が0から2(両方を含む)であると想定しています。

  • 上記の例のRangeは、整数で構成されています。 StringCharacter、浮動小数点小数などのComparableインターフェイスを実装している限り、任意のタイプで構成される範囲を使用できます。

  • ImmutableRangeSetの場合、セットに存在する範囲アイテムは、追加したい範囲アイテムとオーバーラップすることはできません。 その場合、IllegalArgumentExceptionを取得します

  • RangeSetへの範囲入力をnullにすることはできません。 入力がnullの場合、NullPointerExceptionを取得します

4.2. 範囲の削除

RangeSetから値を削除する方法を見てみましょう。

@Test
public void givenRangeSet_whenRemoveRangeIsCalled_removesSucessfully() {
    RangeSet numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 5));
    numberRangeSet.add(Range.closed(6, 8));
    numberRangeSet.add(Range.closed(9, 15));
    numberRangeSet.remove(Range.closed(3, 5));
    numberRangeSet.remove(Range.closed(7, 10));

    assertTrue(numberRangeSet.contains(1));
    assertFalse(numberRangeSet.contains(9));
    assertTrue(numberRangeSet.contains(12));
}

ご覧のとおり、削除後も、セットに残っている範囲アイテムのいずれかに存在する値にアクセスできます。

4.3. 範囲スパン

RangeSetの全体的なスパンを見てみましょう。

@Test
public void givenRangeSet_whenSpanIsCalled_returnsSucessfully() {
    RangeSet numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 5));
    numberRangeSet.add(Range.closed(6, 8));
    Range experienceSpan = numberRangeSet.span();

    assertEquals(0, experienceSpan.lowerEndpoint().intValue());
    assertEquals(8, experienceSpan.upperEndpoint().intValue());
}

4.4. サブレンジの取得

指定されたRangeに基づいてRangeSetの一部を取得する場合は、subRangeSetメソッドを使用できます。

@Test
public void
  givenRangeSet_whenSubRangeSetIsCalled_returnsSubRangeSucessfully() {

    RangeSet numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 5));
    numberRangeSet.add(Range.closed(6, 8));
    RangeSet numberSubRangeSet
      = numberRangeSet.subRangeSet(Range.closed(4, 14));

    assertFalse(numberSubRangeSet.contains(3));
    assertFalse(numberSubRangeSet.contains(14));
    assertTrue(numberSubRangeSet.contains(7));
}

4.5. 補完方法

次に、complementメソッドを使用して、RangeSetに存在する値を除くすべての値を取得しましょう。

@Test
public void givenRangeSet_whenComplementIsCalled_returnsSucessfully() {
    RangeSet numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 5));
    numberRangeSet.add(Range.closed(6, 8));
    RangeSet numberRangeComplementSet
      = numberRangeSet.complement();

    assertTrue(numberRangeComplementSet.contains(-1000));
    assertFalse(numberRangeComplementSet.contains(2));
    assertFalse(numberRangeComplementSet.contains(3));
    assertTrue(numberRangeComplementSet.contains(1000));
}

4.6. 範囲との交差

最後に、RangeSetに存在する範囲間隔が、別の指定された範囲の一部またはすべての値と交差するかどうかを確認する場合は、intersectメソッドを使用できます。

@Test
public void givenRangeSet_whenIntersectsWithinRange_returnsSucessfully() {
    RangeSet numberRangeSet = TreeRangeSet.create();

    numberRangeSet.add(Range.closed(0, 2));
    numberRangeSet.add(Range.closed(3, 10));
    numberRangeSet.add(Range.closed(15, 18));

    assertTrue(numberRangeSet.intersects(Range.closed(4, 17)));
    assertFalse(numberRangeSet.intersects(Range.closed(19, 200)));
}

5. 結論

このチュートリアルでは、いくつかの例を使用して、GuavaライブラリのRangeSetを示しました。 RangeSetは主に、値がセットに存在する特定の範囲内にあるかどうかを確認するために使用されます。

これらの例の実装はthe GitHub projectにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。