Common Groovy Errors

At my work we are using Groovy extensively and often mix Java syntax in Groovy. I want to post some common Groovy language errors that I think everybody in my team has committed at one point when we forget that Groovy is not Java. The first error that I will mention is that use of array initializers. In Java you can construct an array using an initializer like this:

String[] array = new String[]{"one", "two", "three"}

In Groovy, when we attempted to use this construct we would get a nasty and hard to understand compiler exception. Groovy is an expressive language and you can construct an initialized list in the following fashion:

def list = ["one", "two", "three"]   // ArrayList

The list variable is an instance of ArrayList. If you require an array you need to cast the list such as:

def arr = (String[])list   // String array

Now, this leads me to the second compiler error that I have encountered in Groovy. In Groovy I keep writing for loops the Java way:

for(int i; i < list.size(); i++) {
   System.out.println(list.get(i));
}

From my understanding Groovy only supports the for/in loop construct. If you need to iterate over a list using an index you could do the following:

for(i in 0 .. list.size()-1) {
   println list.get(i)
}

If you don’t need the index you can loop over an list in by using the each method provided by the Groovy Development Kit (GDK):

list.each {
   println it
}

Since I mention how to construct an initialized list in Groovy, let me also cover maps. In Groovy you can construct a map by using the following construct:

def map = [name:'Juixe', date:new Date()]

Since map is an instance of HashMap you can retrieve values using the get method but Groovy provides a different mechanism. In Groovy you can access a value from a map like this:

println map['name']   // returns Juixe

In the examples above I have mentioned how to create lists and maps with data. If you need to create a list or map without data you can use one of the following statements:

def emptyList = []
def emptyMap = [:]

A third error that I have commited is that I keep thinking of the each closures as for loops. I have received compilation erros because I try to continue or break out of a closure loop. Closures are code block so you can break out of them using the return keyword. I continue to the next element in a list do something like the following:

[1, 2, 3, 4, 5].each {
  if(it == 3)
	return
  println it
}

Technorati Tags: , , ,