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_4365495446-resized

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

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

記事を読む

no image

CVS でタグ間で変更があったファイルを抽出するスクリプト

今どきバージョン管理ツールに CVS を使っているところは珍しいと思うし、あまり需要はないだろうけど

記事を読む

icatch_5623339500-resized

Bundler を使ってプロジェクト用の Gem をインストールして Gemfile をバージョン管理ツールに登録するまでの流れ

Bundler を使い始める人向けにまとめた次の記事を書きました。 CentOSにRubyのBu

記事を読む

20140811-00

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

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

記事を読む

no image

VPS に Redmine を設置したときに対処したトラブル

Redmine のインストール自体は Redmine 2.3をCentOS 6.4にインストールする

記事を読む

icatch-9214710040_822a4c3456_z-resized

ロードアベレージを監視するシェルスクリプトを作成してみた

このブログを運用している Linux サーバの負荷が高い状態になってました。 何か被害にあったとかで

記事を読む

icatch-2015-004-1

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

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

記事を読む

icatch_8626992930-resized

シェルスクリプトでcdしたいパスにスペースが入っている場合の対処法

cd したいパスにスペースが入っていると、パスの先頭からスペースまでを「移動したいパス」と解釈されて

記事を読む

icatch-pray_c916c87577_mini-thumbnail

Eclipse がエラーメッセージを出力して起動しなくなった場合の対処法

Eclipse の exe ファイルをクリックすると(または、実行すると)、 Eclipse のスプ

記事を読む

icatch-2015-005-1

ユニットテストの偏りを防ぐ命名規則の付け方

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

記事を読む

Googleアドセンス用(PC)

Message

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


一 + 1 =

次の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 ↑