Ranges are lists with sequential values. Each range is also a list object, because Range
extends java.util.List
. A range can be inclusive (so both begin and end values are in the range) or exclusive (the end value is not in the range). We use ..
for an inclusive range and ..<
for an exclusive range.
Each object that implements the Comparable
interface and implements a next()
and previous()
method can be used for a range. So this means we can write our own objects so they can be used in ranges, but also we can use for example String objects or Enum values in a range.
// Simple ranges with number values. def ints = 1..10 assert [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] == ints assert 10 == ints.size() assert 1 == ints.from assert 10 == ints.to // We can step through the values. def list = [] ints.step(2) { list << it } assert [1, 3, 5, 7, 9] == list // A range is just a List. assert 1 == ints[0] assert 10 == ints.last() def s = '' (2..4).each { s += it } assert '234' == s // Exclusive range. def exclusive = 2..<8 assert [2, 3, 4, 5, 6, 7] == exclusive assert 6 == exclusive.size() assert !exclusive.contains(8) // Object with next() and previous() can be used // in ranges. Groovy extends Java enum with // next() and previous() so we can use it in ranges. enum Compass { NORTH, NORTH_EAST, EAST, SOUTH_EAST, SOUTH, SOUTH_WEST, WEST, NORTH_WEST } def northToSouth = Compass.NORTH..Compass.SOUTH assert 5 == northToSouth.size() assert Compass.EAST == northToSouth[2] assert northToSouth.contains(Compass.SOUTH_EAST) // Bonus: next() and previous() are equivalent to // ++ and -- operators. def region = Compass.SOUTH assert Compass.SOUTH_WEST == ++region assert Compass.SOUTH == --region