GroovyとRubyのRangeの違いを前に書きましたが、その関係でGroovyのRangeについても調べたのでまとめます。
基本
ドキュメント
Rangeとは
シーケンシャルな値のリストを保持できるもの。java.util.List
を拡張しているので、Listっぽいアクセスの仕方ができる。
ちなみに、Range自体はインターフェースで、実装としては EmptyRange
, IntRange
, ObjectRange
がある。
インスタンス生成
生成方法
def range = 1..5
assert range == [1, 2, 3, 4, 5]
..
だと、終端(上記のコードだと5)を含むRange、..<
だと終端を含まないRangeを作成できる。
生成されるインスタンスの型について
ちなみに、どのRangeにするかによって、生成されるインスタンスの型が異なる。
def intRange = 1..5
assert range instanceof IntRange
def objectRange = "a".."f"
assert objectRange instanceof ObjectRange
def emptyRange = new EmptyRange()
assert emptyRange instanceof EmptyRange
EmptyRange
はnew
しないとダメっぽい。
参考:http://stackoverflow.com/questions/15485141/empty-groovy-range
アクセス
Listっぽくアクセス
Listを継承しているので、こんな感じにアクセスできる。
def range = 1..5
assert range.size() == 5
assert range.get(2) == 3
assert range[2] == 3
assert range.contains(5)
assert !range.contains(6)
Rangeの中身を変えるアクセスは不可(つまりimmutable)
java.lang.List
を継承しているので、add()
やremove()
といった、Rangeの内容を変更できそうなメソッドが定義されているけど、これらを呼び出そうとすると UnsupportedOperationException
を投げる。
この理由は、ObjectRange
はjava.util.AbstractList
を、IntRange
は、java.util.AbstractList<Integer>
を継承しているため。
参考:http://stackoverflow.com/questions/24889972/why-does-range-throw-unsupportedoperationexception
また、この「サポートされないオペレーションの時はUnsupportedOperationException
を投げる」という仕様は、List
インターフェースに記載されている。
参考:https://docs.oracle.com/javase/jp/8/docs/api/java/util/List.html
イテレーション
each
メソッドを使って走査できる。
(1..5).each {
println "Hello ${i}"
}
swithの条件として使う
ドキュメント見て知ったけど、switch
の条件判定に使える。
switch (age) {
case 1..<6: println "未就学"
case 6..22: println "学生"
default: println "卒業"
}
拡張
独自クラスのRangeを自作する
作成するには、比較のためにjava.lang.Comparable
を実装することと、next()
とprevious()
メソッドを実装する必要がある。
EnumはRangeにできる
Groovyは、JavaのEnum
(Comparable実装済み)に next()
とprevious()
を付け加える。このため、EnumのRangeを作ることができる。
enum DayOfWeek {
SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY
}
def dayRange = DayOfWeek.SUNDAY..DayOfWeek.WEDNESDAY
assert dayRange.size() == 4
assert dayRange.contains(DayOfWeek.MONDAY)
assert !dayRange.contains(DayOfWeek.THURSDAY)
参考:http://mrhaki.blogspot.jp/2009/09/groovy-goodness-keep-your-values-in.html
Range、いろいろ便利だ。