Showing posts with label operator. Show all posts
Showing posts with label operator. Show all posts

Wednesday, February 10, 2010

Spread operator

Spread operator helps Groovy collections (list, range and map) to simple comma separated values. Spread operator is so flexible which can be used anywhere. For example:

def test(a, b, c){
return a + b + c
}

def numList = [1, 2, 3]

If you want to pass the above list of values to the test() method you have to write some boilerplate code to extract the elements and pass them in the method.

Whereas the spread operator is introduced to eliminate boilerplate code and follow clean coding. The above method can be called with the given list without a single extra line of code.

test(*numList)

An asterisk followed by list, range or map will spread the collection and convert all the containing values to comma separated values. The above example will work same for Range.

def numRange = 1..3
test(*numRange)

Map has different syntax compared to List and Range.

def aMap = [a:1, b:2]
def bMap = [c:3, *:aMap]

Likewise Groovy contains many such shortening facilities where development time can be reduces and code can remain clear and understandable.

Groovy spread-dot operator in GPath

GPath is an expression language integrated into Groovy to process nested objects. The dot and spread-dot operators helps to build the GPath expression. The dot operator is used to access the properties and spread-dot operator is used to access property, field or method.

class Person{
String firstName
String lastName
int age

int calc(){
return age * 2
}
}

def personList = [
new Person(firstName: "dhaval", lastName: "nagar", age: 25),
new Person(firstName: "nachiket", lastName: "patel", age: 24)
]

To access the firstName property one can use either of the operators:

println personList.firstName
// ["dhaval", "nachiket"]

println personList*.firstName
// ["dhaval", "nachiket"]

To access the calc() method spread-dot operator has to be used, whereas dot operator will raise an exception:

println personList*.total()
// [50, 48]

Apart from the access restrictions both the operators works differently when collection contains null values like:

personList << null
personList << new Person(firstName: "sandeep", lastName: "shah", age: 30)

println personList.firstName
// ["dhaval", "nachiket", "sandeep"]

println personList*.firstName
// ["dhaval", "nachiket", null, "sandeep"]

The spread-dot operator will add the null value for each null element in the resulting list.

Both the operators works same when the list element is not null but the requested property is null.

personList.clear()
personList << new Person(firstName: "dhaval", lastName: "nagar", age: 25)
personList << new Person(lastName: "nagar", age: 25)

println personList.firstName
// ["dhaval", null]

println personList*.firstName
// ["dhaval", null]

To avoid such null values in the resulting list, grep expression can be used.

println personList.grep{it?.firstName}.firstName
// ["dhaval"]

Here grep will try to evaluate the true boolean condition, as per the Groovy Truth if an object is NULL it will be considered as FALSE. So above expression will reject all the objects where firstName property value is null.