QuickTip: Reversing Sort Order in Groovy

One of the great things about Groovy is that there are multiple ways to get **it done. This means people learning Groovy and especially those coming from other programming languages can use the same syntax and practices they are already familiar with. However, this may result in some small mistakes or inefficiencies.

The first one I want to highlight today is reverse sorting.

So given:

 class Person {  
   String name  
   Integer age  
 }  

If we want to sort a list of people by their age, we would normally use:

 people.sort { it.age }  

To reverse the list, we have several options including:

 people.sort { it.age }.reverse()  

or:

 people.sort { -it.age }  

The first one, I see a lot. It's easy to write and to think about, but it's not as efficient as the second one. Why sort the list and then reverse it, when you can sort by the criteria you want in the first place?

The next problem comes with the '-' notation. It works great for examples like this when we are sorting by simple types like Integers. But, what happens when instead of age, we change the person class to use a Date type?

 class Person {  
   String name  
   Date birthday  
 }  

if you try,
 people.sort { -it.birthday}  
you'll get this message:

 groovy.lang.MissingMethodException: No signature of method: java.util.Date.negative() is applicable for argument types: () values: []  
 Possible solutions: getTime(), setTime(long), notify(), getDate(), next()  
 at Script1.run(Script1.groovy:10)  

From looking at StackOverflow questions, this is the reason why a lot of people use the sort then reverse pattern.

What we can do instead, is switch the sorting order using the spaceship(<=>) operator.

 people.sort { a,b -> b.birthday <=> a.birthday }  

Hopefully, this short tip helps you write more efficient Groovy code!

Comments