Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 2 Next »

The prerequisite is that you are familiar with standard assignment and arithmetic operators. If not, read the official Groovy documentation first.

Ternary Operator ? x : y

This operator is a shortcut to writing the following:

if (product.label != null && product.label.length() > 0) {
	return product.label
} else {
	return 'N/A'
}

You can rewrite this using the ternary operator:

return (product.label != null && product.label.length() > 0) ? product.label : 'N/A'

Or even simplify it:

return product.label ? product.label : 'N/A'


Elvis Operator ?:

This operator is a very useful shortcut to writing this:

return product.label ? product.label : 'N/A'  // ternary operator 
return product.label ?: 'N/A' // Elvis operator

You can rewrite it like this:

date = api.targetDate() ?: new Date() // if target date is null, we use the current date

Or:

lookback = api.decimalUserEntry('Look-back period (default: 20)') ?: 20 // if the user doesn't specify the look-back period, it will default to 20

In case you wonder why this is called Elvis operator...

?: →  rotate 90° right → → 

Safe Navigation Operator ?.

When you check for a null reference every time you want to access object's attribute or method, you might be using something like:

if (date) {
	return date.format('yyyy-MM-dd')
} 
return null

Advanced Groovy allows you to use the ternary operator:

return date ? date.format('yyyy-MM-dd') : null

But even better is to use the Safe navigation operator:

return date?.format('yyyy-MM-dd')

If the date is null, the whole expression will evaluate to null. You can even chain the calls:

return product?.attribute21?.toBigDecimal()

Spread Operator *

Sometimes you may want to pass a collection of objects to a method which accepts a variable name of parameters only. Such as Filter.or:

def filters = [
  Filter.equal('attribute5', 'P'),
  Filter.equal('attribute5', 'M'),
  Filter.equal('attribute5', 'U'),
]
 
// this will throw a compilation error as Filter.or doesn't accept a collection but a variable number of Filter arguments
api.find('P', Filter.or(filters))

What you need to do is to use the simple * operator to spread the collection of Filters over the Filter.or method.

def filters = [
  Filter.equal('attribute5', 'P'),
  Filter.equal('attribute5', 'M'),
  Filter.equal('attribute5', 'U'),
]
 
// notice the * char. This will unwrap each element of the collection and pass it to the method as a separate parameter
api.find('P', Filter.or(*filters))

Spaceship Operator <=>

This operator delegates to the compareTo method of the left-side operand and passes it the right-side operand.  

assert (1 <=> 1) == 0
assert (1 <=> 2) == -1
assert (2 <=> 1) == 1
assert ('a' <=> 'z') == -1

It is best when mixed with a sort method.

def competitors = api.productExtension('Competition')
def sortedByName = competitors .sort { a, b -> return a.attribute1 <=> b.attribute1 } // assuming attribute1 is the name of the competitor
  • No labels