def myIntRage = 6..10 println "Class is: ${myIntRage.class}" println "Implements List?: ${myIntRage instanceof java.util.List}" println "Contents are: ${myIntRage}" println "First item: ${myIntRage[0]}" println "Second item: ${myIntRage[1]}" println "Third item: ${myIntRage[2]}" println "Fourth item: ${myIntRage[3]}" println "Fifth item: ${myIntRage[4]}"The notation .. creates a list of numbers from 6 up to 10. It is a quick way of creating a sequential list without actually declaring each particular content, which could be tedious or unpractical. Here is the expected output:
Class is: class groovy.lang.IntRange Implements List?: true Contents are: [6, 7, 8, 9, 10] First item: 6 Second item: 7 Third item: 8 Fourth item: 9 Fifth item: 10Because it is a list, it supports many functions inherent to a List.
def myIntRage = 6..10 println "Size is: ${myIntRage.size()}" println "Item at index 2 is: ${myIntRage.get(2)}" println "Does it contain 8?: ${myIntRage.contains(8)}" println "Does it contain 11?: ${myIntRage.contains(11)}" println "Does it contain 7 and 10?: ${myIntRage.containsAll([7, 10])}" println "Does it contain 9 and 12?: ${myIntRage.containsAll([9, 12])}" println "What is the index of the item with vaue 7?: ${myIntRage.indexOf(7)}" println "Is the list empty?: ${myIntRage.isEmpty()}"
And the result is shown below. Note that the methods invoked are part of Java's java.util.List interface.
Size is: 5 Item at index 2 is: 8 Does it contain 8?: true Does it contain 11?: false Does it contain 7 and 10?: true Does it contain 9 and 12?: false What is the index of the item with vaue 7?: 1 Is the list empty?: false
We can iterate an IntRage using for loop, example:
def myIntRange = 11..15 for (n in myIntRange) { println n }
Will display:
11 12 13 14 15
And also iterate using Groovy each:
def myIntRange = 21..25 myIntRange.each { n -> println n }
Will output:
21 22 23 24 25
We can define a range in decreasing value:
def myIntRage = 100..90 println "Values: ${myIntRage}"
Will yield the output:
Values: [100, 99, 98, 97, 96, 95, 94, 93, 92, 91, 90]
Increments of IntRange don't necessarily need to be 1. It can be customized using step. Example:
def myIntRage = (1..10).step(2) println "Values: ${myIntRage}" def anotherIntRage = (2..10).step(2) println "Values: ${anotherIntRage}" def yetAnotherIntRage = (2..10).step(3) println "Values: ${yetAnotherIntRage}"
Will have the output below. Notice that the first element is always the from value. Succeeding values follows the step defined.
Values: [1, 3, 5, 7, 9] Values: [2, 4, 6, 8, 10] Values: [2, 5, 8]
And we can also do step in reverse order. For example:
def myIntRage = (10..1).step(2) println "Values: ${myIntRage}" def anotherIntRage = (9..1).step(2) println "Values: ${anotherIntRage}" def yetAnotherIntRage = (10..1).step(3) println "Values: ${yetAnotherIntRage}"
Will output the following:
Values: [10, 8, 6, 4, 2] Values: [9, 7, 5, 3, 1] Values: [10, 7, 4, 1]
def myIntRange = 11..<15 println "Values: ${myIntRange}"
The list will have the values from 11 to 15, but excluding the upper bound 15.
Values: [11, 12, 13, 14]
We can declare half open on a decreasing range of values:
def myIntRange = 25..<21 println "Values: ${myIntRange}"
Will yield the result:
Values: [25, 24, 23, 22]
We can also use Range on non Integer values, this will have the instance of ObjectRange. Here is an example:
def myObjectRange = 'a'..'c' println "Class: ${myObjectRange.class}" println "Values: ${myObjectRange}"
This is the output. It creates an ObjectRange with three items, the Strings 'a', 'b', and 'c':
Class: class groovy.lang.ObjectRange Values: [a, b, c]
We can do more than iterating over characters. For example:
def myObjectRange1 = 'Ball1'..'Ball5' def myObjectRange2 = 'Balla'..'Balle' println "Values: ${myObjectRange1}" println "Values: ${myObjectRange2}"
Will have the output below.
Values: [Ball1, Ball2, Ball3, Ball4, Ball5] Values: [Balla, Ballb, Ballc, Balld, Balle]
It is smart enough when only the last character will increment. But not smart enough when two characters are involved. For example:
def myObjectRange = 'Ball11'..'Ball22'
Will throw an exception:
Caught: java.lang.IllegalArgumentException: Incompatible Strings for Range: String#next() will not reach the expected value java.lang.IllegalArgumentException: Incompatible Strings for Range: String#next() will not reach the expected value at Test.run(Test.groovy:1)
But is smart enough to understand reverse range:
def myObjectRange = 'Ball5'..'Ball1' println "Values: ${myObjectRange}"
Will yield:
Values: [Ball5, Ball4, Ball3, Ball2, Ball1]
ObjectRange also allows non integer values. For example:
def myObjectRange = 1.5..5 println "Class: ${myObjectRange.class}" println "Values: ${myObjectRange}"
The behavior is similar to IntRange where the step defaults to 1.
Class: class groovy.lang.ObjectRange Values: [1.5, 2.5, 3.5, 4.5]
But we can use step explicitly:
def myObjectRange = (1.5..10).step(2) println "Values: ${myObjectRange}"
Will print:
Values: [1.5, 3.5, 5.5, 7.5, 9.5]
But we may not use non integer step. For example:
def myObjectRange = (1.5..10).step(1.5)
Will throw:
Caught: groovy.lang.MissingMethodException: No signature of method: groovy.lang.ObjectRange.step() is applicable for argument types: (java.math.BigDecimal) values: [1.5] Possible solutions: step(int), step(int, groovy.lang.Closure), grep(), grep(), sleep(long), grep(java.lang.Object) groovy.lang.MissingMethodException: No signature of method: groovy.lang.ObjectRange.step() is applicable for argument types: (java.math.BigDecimal) values: [1.5] Possible solutions: step(int), step(int, groovy.lang.Closure), grep(), grep(), sleep(long), grep(java.lang.Object) at Test.run(Test.groovy:1)