Getting Groovy, Part II

Written By: James Williams

- 28 Jul 2006 -

Description: This tutorial introduces you to Groovy, a dynamically-typed scripting language for the Java Virtual Machine. Part II introduces for loops, switch-case, collections, and closures.

  1. For-Loop and Switch
  2. Collections
  3. Closures

Closures

A closure is a reusable block of code with a built-in parameter it. Additional parameters can be specified if needed. Closures can be called on individual objects, are first-class objects themselves, and storeable in arrays and hashs.

We can create custom closures or add our code to pre-defined closure targets.

The general format of the closure body is

{ [optional parameters] -> [code] }

Either of these is valid for defining a closure that prints Hello and the name:

hi = { println "Hi" }
 
hello = { println "Hello" + it } 
hello = { it -> println "Hello ${it}"}               // ${variable} is how to include variables without a
//bunch of + signs
hello = {println "Hello ${it}"}

Let's redo our n-factorial function from part one to make it groovier:

fact = { if (it == 1) 
                return 1
        else return it*fact(it-1)
}

We can call closures like functions, or with the call keyword. Any of these are valid:

hi() hi.call
hello "John" hello("John") hello.call "John" hello.call("John")
fact 5 fact(5) fact.call 5 fact.call(5)

The real power of closures is realized when combined with collections and primitive objects.

Instead of using a for or while loop, we could use:

3.times { println "Hi" } 
 
1.upto(5) { println it } 
 
20.downto(15) { println it}

Collections have a bunch of predefined closure targets but for brevity, I'll only talk about my favorites: each and findAll.

each iterates through the collection and executes the closure code on each element. findAll returns a new collection with the elements that satisfy the conditions of the closure.

[1,2,3].each {println it*it}              //prints 1
                                        //       4
                                        //       9
 
["Jake","John","Cody","Christine"].findAll { it.startsWith("C") } 
// returns ["Cody", "Christine"] 

<< Previous