Working with Maps

A map is an unordered collection of name/value pairs. The name in each name/value pair is called the map's key for that entry since it is the key to looking up the value in the map later.

You can create a map using Groovy's square-bracket notation, using a colon to separate each key and value, and a comma between each key/value pair like this:

// Define a map of name/value pairs that associate
// a status value (e.g. "Open", "Closed", "Pending") with a
// maximum number of days
def maxDaysByStatus = [Open:30, Closed:90, Pending:45]

Notice that by default, the map key is assumed to be a string so you don't need to include the key values in quotes. However, if any key value contains spaces you will need to use quotes around it like this:

def maxDaysByStatus = [Open:30, Closed:90, Pending:45, 'On Backorder':10]

If you want to use another type as the map key, you need to surround the key with parentheses. Consider the following example without the parentheses:

def x = 1
def y = 2
def xvalue = 'One'
def yvalue = 'Two'
// this creates a map with entries ('x'->'One') and ('y'->'Two')
def m = [x:xvalue,y:yvalue]

The above example creates a map with key values of the strings x and y, rather than using the value of the variable x and the value of the variable y as map keys. To obtain this effect, surround the key expressions with parentheses like this:

def x = 1
def y = 2
def xvalue = 'One'
def yvalue = 'Two'
// this creates a map with entries (1->'One') and (2->'Two')
def m = [(x):xvalue,(y):yvalue]

This creates a map with key values of the numbers 1 and 2.

To reference the value of a map entry, use dot notation like this, using the may key value as if it were a field name on the map object:

def closedDayLimit = maxDaysByStatus.Closed

If the key value contains a literal dot character or contains spaces or special characters, you can also use the square-bracket notation, passing the key value as the operand:

def onBackorderDayLimit = maxDaysByStatus['On Backorder']

This square bracket notation is also handy if the key value is coming from the value of a variable instead of a literal string, for example:

// Loop over a list of statuses to process
for (curStatus in ['Open','On Backorder']) {
  def limitForCurStatus = maxDaysByStatus[curStatus]
  // do something here with the current status' limit
}  

To add an new key/value pair to the map, use the put() method:

// Add an additional status to the map
maxDaysByStatus.put('Ringo')

A map cannot contain duplicate key entries, so if you use put() to put the value of an existing element, the existing value for that key is overwritten. You can use the containsKey() function to test whether or not a particular map entry already exists with a given key value, or you can use the containsValue() function to test if any map entry exists that has a given value — there might be zero, one, or multiple entries!

// Test whether a map key matching the value of the
// curKey variable exists or not
if (maxDaysByStatus.containsKey(curKey)) {
  def dayLimit = maxDaysByStatus[curKey]
  // do something with dayLimit here
}
else {
  println("Unexpected error: key ${curKey} not found in maxDaysByStatusMap!")
}

To remove an entry from the map, use the remove() method. It returns the value that was previously associated with the key passed in, otherwise it returns null if it did not find the given key value in the map to remove.

maxDaysByStatus.remove('On Backorder')

You can define an empty map using the square-bracket notation with only a colon inside like this:

def foundItemCounts = [:] // empty map!