グアバレンジセットガイド
1概要
このチュートリアルでは、Google Guavaの
RangeSet
インターフェイスとその実装の使い方を説明します。
RangeSet
は、0個以上の空でない切断された範囲で構成される集合です。可変の
RangeSet
に範囲を追加すると、空の範囲は無視されますが、接続されている範囲はすべてマージされます。
RangeSet
の基本的な実装は
TreeRangeSet
です。
2 Google Guavaの
RangeSet
RangeSet
クラスの使い方を見てみましょう。
2.1. Mavenの依存関係
まず、
pom.xml
にGoogleのGuavaライブラリ依存関係を追加します。
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>21.0</version>
</dependency>
依存関係の最新バージョンはhttps://search.maven.org/classic/#search%7C1%7Cg%3A%22com.google.guava%22%20AND%20a%3A%22guava%22[]で確認できます。ここに]。
3作成
RangeSet
のインスタンスを作成する方法をいくつか探りましょう。
まず、クラス
TreeRangeSet
の
create
メソッドを使用して可変セットを作成します。
RangeSet<Integer> numberRangeSet = TreeRangeSet.create();
コレクションがすでに用意されている場合は、クラス
TreeRangeSet
の
create
メソッドを使用して、そのコレクションを渡して可変セットを作成します。
List<Range<Integer>> numberList = Arrays.asList(Range.closed(0, 2));
RangeSet<Integer> numberRangeSet = TreeRangeSet.create(numberList);
最後に、不変の範囲セットを作成する必要がある場合は、
ImmutableRangeSet
クラスを使用します(作成パターンはビルダーパターンに従います)。
RangeSet<Integer> numberRangeSet
= new ImmutableRangeSet.<Integer>builder().add(Range.closed(0, 2)).build();
4使用法
RangeSet
の使い方を示す簡単な例から始めましょう。
4.1. 範囲に追加する
提供された入力が、セット内のいずれかの範囲項目に存在する範囲内にあるかどうかを確認できます。
@Test
public void givenRangeSet__whenQueryWithinRange__returnsSucessfully() {
RangeSet<Integer> 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
は整数で構成されています。範囲を使用できます
Comparable
を実装している限り、任意の型からなる
String
、
Character
、浮動小数点数などのインタフェース
**
ImmutableRangeSet
の場合、セット内に存在する範囲項目
追加したい範囲項目と重複することはできません。もしそうなら
起こる、我々は
IllegalArgumentException
を得る
**
RangeSet
への範囲入力はnullにできません。入力が
null
の場合、
NullPointerException
が発生します
4.2. 範囲を削除する
RangeSet
から値を削除する方法を見てみましょう。
@Test
public void givenRangeSet__whenRemoveRangeIsCalled__removesSucessfully() {
RangeSet<Integer> 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<Integer> numberRangeSet = TreeRangeSet.create();
numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
Range<Integer> 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<Integer> numberRangeSet = TreeRangeSet.create();
numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
RangeSet<Integer> 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<Integer> numberRangeSet = TreeRangeSet.create();
numberRangeSet.add(Range.closed(0, 2));
numberRangeSet.add(Range.closed(3, 5));
numberRangeSet.add(Range.closed(6, 8));
RangeSet<Integer> 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<Integer> 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
は、値がセット内に存在する特定の範囲内にあるかどうかを確認するために主に使用されます。
これらの例の実装はhttps://github.com/eugenp/tutorials/tree/master/guava-collections[GitHubプロジェクト]にあります – これはMavenベースのプロジェクトです。そのまま実行します。