GoogleGuavaのRangeを使って範囲判定を簡潔に書く

公開日: : プログラム ,

次のような判定処理を if 文で書くことがよくある。

  • もし 100 よりも大きければ(=大小判定)
  • ◯◯が 100 以上 200 未満なら(=範囲判定)

比較される 100 とか 200 といった数に「名前」を持たせたり、if 文の条件式をメソッドに切り出して「名前」を持たせたりしている。
これはデバッグや改修で未来の自分がコードを読んだときに思い出すのを手助けするためにやっている作業だ。
この作業に GoogleGuava の Range クラスを使うと、さらに可読性が上がるかもしれないと思ったので検証してみた。

目次

1. Range クラスとは

GoogleGuava の Range クラスは、数値の大小判定や範囲判定の定義を行うクラス。
判定とは、「◯◯未満か」とか「この範囲内に含まれるか」といった処理を指す。

この Range クラスを使うことで条件式がもっと読みやすくなるのではないかと個人的に期待している。
色んなことが許される範囲で積極的に使ってみる。

2. GoogleGuava の Range クラスを使った大小判定

検証した大小判定は以下の4パターン。

  1. 100 以上(at least)
  2. 100 よりも大きい(greater than)
  3. 100 以下(at most)
  4. 100 未満(less than)

以下はそれぞれのパターンの検証。

1-1. 100 以上(at least)

「100 以上」を表すインスタンスは次のように生成する。

Range.atLeast(100);

大小判定は Range#contains() を使う。
以下は 99、100、101 と比較した場合。

Range.atLeast(100).contains(99); // 結果は `false` になる
Range.atLeast(100).contains(100); // 結果は `true` になる
Range.atLeast(100).contains(101); // 結果は `true` になる

1-2. 100 よりも大きい(greater than)

「100 よりも大きい」を表すインスタンスは次のように生成する。

Range.greaterThan(100);

99、100、101 と比較してみる。

Range.greaterThan(100).contains(99); // 結果は `false` になる
Range.greaterThan(100).contains(100); // 結果は `false` になる
Range.greaterThan(100).contains(101); // 結果は `true` になる

1-3. 100 以下(at most)

「100 以下」の場合。

Range.atMost(100);

99、100、101 と比較してみる。

Range.atMost(100).contains(99); // 結果は `true` になる
Range.atMost(100).contains(100); // 結果は `true` になる
Range.atMost(100).contains(101); // 結果は `false` になる

1-4. 100 未満(less than)

最後に「100 未満」の場合。

Range.lessThan(100);

99、100、101 との比較。

Range.atMost(100).contains(99); // 結果は `true` になる
Range.atMost(100).contains(100); // 結果は `false` になる
Range.atMost(100).contains(101); // 結果は `false` になる

単純な条件式では Range を使うとタイプ量が増えるかもしれない。
が、条件式が「数式」ではなく「文章」っぽくなって読みやすくなるので別に気にしない。

3. GoogleGuava の Range クラスを使った範囲判定

検証した範囲判定は以下の4パターン。

  1. 100 以上 かつ 200 以下(closed)
  2. 100 以上 かつ 200 未満(closed open)
  3. 100 よりも大きい かつ 200 以下(open closed)
  4. 100 よりも大きい かつ 200 未満(open)

以下はそれぞれのパターンの検証。

3-1. 100 以上 かつ 200 以下(closed)

「100 以上 かつ 200 以下」を表すインスタンスは次のように生成する。

Range.closed(100, 200);

範囲判定も Range#contains() を使う。
以下は 99、100、101、199、200、201 と比較した場合。

Range.closed(100, 200).contains(99); // 結果は `false` になる
Range.closed(100, 200).contains(100); // 結果は `true` になる
Range.closed(100, 200).contains(101); // 結果は `true` になる
Range.closed(100, 200).contains(199); // 結果は `true` になる
Range.closed(100, 200).contains(200); // 結果は `true` になる
Range.closed(100, 200).contains(201); // 結果は `false` になる

3-2. 100 以上 かつ 200 未満(closed-open)

「100 以上 かつ 200 未満」の場合。

Range.closedOpen(100, 200);

99、100、101、199、200、201 との比較。

Range.closedOpen(100, 200).contains(99); // 結果は `false` になる
Range.closedOpen(100, 200).contains(100); // 結果は `true` になる
Range.closedOpen(100, 200).contains(101); // 結果は `true` になる
Range.closedOpen(100, 200).contains(199); // 結果は `true` になる
Range.closedOpen(100, 200).contains(200); // 結果は `false` になる
Range.closedOpen(100, 200).contains(201); // 結果は `false` になる

3-3. 100 よりも大きい かつ 200 以下(open-closed)

「100 よりも大きい かつ 200 以下」の場合。

Range.openClosed(100, 200);

99、100、101、199、200、201 との比較。

Range.openClosed(100, 200).contains(99); // 結果は `false` になる
Range.openClosed(100, 200).contains(100); // 結果は `false` になる
Range.openClosed(100, 200).contains(101); // 結果は `true` になる
Range.openClosed(100, 200).contains(199); // 結果は `true` になる
Range.openClosed(100, 200).contains(200); // 結果は `true` になる
Range.openClosed(100, 200).contains(201); // 結果は `false` になる

3-4. 100 よりも大きい かつ 200 未満(open)

「100 よりも大きい かつ 200 未満」の場合。

Range.open(100, 200);

99、100、101、199、200、201 との比較。

Range.open(100, 200).contains(99); // 結果は `false` になる
Range.open(100, 200).contains(100); // 結果は `false` になる
Range.open(100, 200).contains(101); // 結果は `true` になる
Range.open(100, 200).contains(199); // 結果は `true` になる
Range.open(100, 200).contains(200); // 結果は `false` になる
Range.open(100, 200).contains(201); // 結果は `false` になる

openClosed() などのメソッド名と条件式がすぐに結び付けば読みやすくなる印象。覚えるしかない。

4. 更新履歴

  • 2015/10/07: 初版作成

Googleアドセンス用(PC)

  • このエントリーをはてなブックマークに追加
  • follow us in feedly

関連記事

icatch-back-scratcher_3553512020_mini-thumbnail

Sublime Text3 で JavaScript を書くために設定したプラグインとキーバインド

プロフィール にもあるように、ボクは Java をメインとしたプログラマです。 IDE には Ecl

記事を読む

no image

no space left と表示されたときの対処法

タイトルの "no space left" とは「書き込みたいけど、ディスクの飽

記事を読む

no image

IE9 のキャッシュ対策

どのようなバグだったのか POST で送信した内容を確認する画面で、最新の内容が表示されないという

記事を読む

icatch-medium_4301351732-resized

mp3splt を実行して “undefined symbol: mp3splt_u_check_if_directory” と出力されたときの対処法

mp3 ファイルを分割してくれる mp3splt というライブラリがあります。 mp3 ファイルを

記事を読む

icatch_4365495446-resized

CentOS6.5にGitをソースコードからインストールする

CentOS 6.5 の64ビット版を "Minimal" でインストールした環境で、git sta

記事を読む

icatch-thumbup_3507728739_mini-thumbnail

Sublime Text3 に SublimeLinter-jshint をインストールしてみた

エディタに Eclipse を使って Java のプログラムを書くことが多いんですが、JavaScr

記事を読む

icatch_5428744075-resized

scp を使ってファイルのコピーを実行したら “command not found” と表示されたときの対処法

CentOS が起動しているサーバに scp を使ってファイルをコピーしようとコマンドを実行したら

記事を読む

icatch_3304032405-resized

CentOS に yum-plugin-priorities プラグインをインストールする

yum を使ってあるパッケージをインストールしようと調べていたところ、yum-plugin-prio

記事を読む

icatch-vagrant_box_customize

VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を構築することが多くなってきた。

記事を読む

20140811-00

64ビット版のCentOSをVMwareにインストールできない場合の対処法

Linux で検証したい作業が多かったので VMware に検証環境を作りました。OS は Cent

記事を読む

Googleアドセンス用(PC)

Message

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です


九 × 7 =

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Googleアドセンス用(PC)

icatch-jersey_multi_pathparams
Jerseyの@PathParamはスラッシュの間に複数指定できる

http://hoge-api/user/{id}.{format}

icatch-vagrant_box_customize
VagrantのBoxファイルをカスタマイズして独自のBoxファイルを作成する

配布されている Vagrant の Box ファイルを使って検証環境を

icatch-2015-006-1
バリデーションチェックにJava8のOptionalを使ってスマートに書く(自分比)

Web アプリのバリデーションチェックにアノテーションを使うことが増え

icatch-2015-005-1
ユニットテストの偏りを防ぐ命名規則の付け方

ユニットテスト名に以下の命名規則を付けるようにして二ヶ月ぐらい経った。

icatch-2015-004-1
Vagrantで起動したCentOS上のOctopressをホストOSから確認する設定

タイトルの通りだが、Vagrant を使って起動した CentOS に

→もっと見る

PAGE TOP ↑