An extension for Groovy Lists – getting the only element of a list

This is the first post about an extension library I wrote for use in Groovy projects.

A little background

Groovy is a programming language which runs on the JVM (Java Virtual Machine). Any computer or device that can run Java programs can also run programs written in Groovy and it enhances the Java programming language in many ways. I won’t go into them all here but for anyone who develops in Java I would recommend checking it out for its expressiveness, power, and speed of development.

In version 2 of Groovy there is a new mechanism for adding extensions to pre-existing classes. Groovy uses the same mechanism to extend some of Java’s classes. This is the mechanism I used to write my extensions library. You can find more information at http://groovy.codehaus.org/Groovy+2.0+release+notes#Groovy2.0releasenotes-Extensionmodules. I used Tim Yatesgroovy-common-extensions library as an example of this sort of extension library and based some of my build code from there. It has some interesting extensions itself and is worth checking out.

Groovy Lists

One of the features Groovy provides is a number of extensions to many of the common Java classes and interfaces. For example the List class has been given the following methods:

first()
Returns the first element of the list.
last()
Returns the last element of the list.
head()
Returns the first element of the list (aka the ‘head’ of the list).
tail()
Returns the remaining elements of the list, ignoring the ‘head’.

I find these extremely useful. They make the code read much better; consider the following alternatives:

Player nextPlayer = remainingPlayers[0]

or

Player nextPlayer = remainingPlayers.first()

I find the second option much more expressive and requires less mental energy to understand what is going on.

My own contribution: only()

I find using first(), last(), etc. to be very expressive. But I felt there was an additional case which wasn’t really handled. My theory is that there are times when you know that there will only be one element in a list. Consider this example using a fictional utility class, SqlUtility, which will execute some SQL and return a list of results representing the rows:

def results = SqlUtility.execute('SELECT TOP 1 * FROM players ORDER BY score DESC;')

Here we know that will only be one element in the list and that it is the element that we are interested in. We could get the element we know like so:

def winningPlayer = results.first()

The problem I see with this is that it doesn’t convey the knowledge we have that there will only be one element. A reader could reasonably see this code and think to themselves “we’re getting the first result, what about the rest?”. I could have also chosen to write it as such:

def winningPlayer = results.last()

This code would give the same result in this case (the list would contain the same, single element) but it would also leave the reader unsatisfied about why that particular element is the one we are interested in (e.g. “why the last element?”, “what comes before it?”). When they see the SQL they will probably realise that there is only the one element, but this line of code could convey this information too, and there wouldn’t be any hesitation and needing to look back at earlier code. This is the reason I added the only() method to the List class. Our code can now be written as this:

def winningPlayer = results.only()

It follows the same semantics as the other List methods I’ve mentioned. It will throw a NoSuchElementException if the list is empty. It will also throw a MoreThanOneElementException if there is more than one element in the list. Both of these Exceptions could be used to handle the case where your program isn’t doing what it should be doing.

I imagine that not everyone will like this new behaviour; particularly the checks that are performed. The other List methods (and my only() method) throw a NoSuchMethodExtension to indicate when they can’t do their job. This is very different from the reason that my only() method throws a MoreThanOneElementException. At this point my function is verifying that the program is in a certain state. This is the same thing you would normally achieve with an assert statement. So not everyone would like to have this sort of verification hidden in a method like this.

More info

The GitHub repo for the library: https://github.com/dnahodil/groovy-extra-list-behaviour
Update:

There are now two follow-up posts to this one. One to explain some other functions which were added, and the other explaining how to use extension libraries in a Grails application.

Leave a comment