+ All Categories
Home > Documents > Groovy Goodness Notebook Sample

Groovy Goodness Notebook Sample

Date post: 29-Jan-2016
Category:
Upload: ijazkhan
View: 105 times
Download: 9 times
Share this document with a friend
Description:
Groovy Goodness Notebook Sample
23
Transcript
Page 1: Groovy Goodness Notebook Sample
Page 2: Groovy Goodness Notebook Sample

Groovy Goodness NotebookExperience the Groovy programming language through code snippets

Hubert A. Klein Ikkink (mrhaki)

This book is for sale at http://leanpub.com/groovy-goodness-notebook

This version was published on 2015-08-24

This is a Leanpub book. Leanpub empowers authors and publishers with the Lean Publishing process.Lean Publishing is the act of publishing an in-progress ebook using lightweight tools and manyiterations to get reader feedback, pivot until you have the right book and build traction once you do.

©2012 - 2015 Hubert A. Klein Ikkink (mrhaki)

Page 3: Groovy Goodness Notebook Sample

Tweet This Book!

Please help Hubert A. Klein Ikkink (mrhaki) by spreading the word about this book on Twitter!

The suggested tweet for this book is:

I just bought Groovy Goodness Notebook with Groovy Goodness blog posts bundled into one book.#groovy @mrhaki

The suggested hashtag for this book is #groovygoodnessnotebook.

Find out what other people are saying about the book by clicking on this link to search for this hashtagon Twitter:

https://twitter.com/search?q=#groovygoodnessnotebook

Page 4: Groovy Goodness Notebook Sample

Also By Hubert A. Klein Ikkink (mrhaki)Grails Goodness Notebook

Gradle Goodness Notebook

Spocklight Notebook

Awesome Asciidoctor Notebook

Page 5: Groovy Goodness Notebook Sample

This book is dedicated to my lovely family. I love you.

Page 6: Groovy Goodness Notebook Sample

Contents

Dates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Working with Dates . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1Setting Date and Calendar Values with Subscript Operators . . . . . . . . . . . . . . . . . . . . 2Convert Date to java.sql.Timestamp . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2Convert Date to Calendar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3Format Dates with TimeZone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3Parse Date.toString() Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4Use the set Method to Define a Date or Calendar Value . . . . . . . . . . . . . . . . . . . . . . 5Create New Date from Old Date with Updates . . . . . . . . . . . . . . . . . . . . . . . . . . . 5Create New Date or Calendar from Existing and Set Property Value . . . . . . . . . . . . . . . 6Clear Time Portion of a Date . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6Date and Time Durations and the TimeCategory . . . . . . . . . . . . . . . . . . . . . . . . . . 7Loop Through Date and Calendar Ranges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10Check if Maps are Equal . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10Sorting a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10Turn a List into a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Complex Keys in Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11Use inject Method on a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Intersect Maps . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Subtracting Map Entries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12Process Map Entries in Reverse . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13Getting a Submap from a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13Grouping Map Elements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14Get Value from Map or a Default Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15Map with Default Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16Determine Min and Max Entries in a Map . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16

Page 7: Groovy Goodness Notebook Sample

Dates

Working with Dates

Thanks to Groovy’s extensions to the JDK Date classes we can work with dates more easily. For examplewe can now add and subtract days with the plus() and minus() methods. And because this methods aremapped to the operators + and - we can write dense code.

Also the next() and previous() methods are implemented so we can use the ++ and -- operators to getto a next or previous day. We can even use the subscript operator ([]) to get date fields, because of thegetAt() method Groovy adds to the Date class.

The Date class also contains parse() and format() methods to convert string to a date and to format adate into a string.

// Date.parse() to convert String to Date.

date = new Date().parse('yyyy/MM/dd', '1973/07/09')

// We can use [] or getAt() to get date fields.

assert 1973 == date[Calendar.YEAR]

assert 6 == date[Calendar.MONTH]

assert 9 == date.getAt(Calendar.DATE)

dateNext = date.clone()

datePrevious = date.clone()

// We can use the + and - operators to add or

// subtract days.

nextDay = date + 1 // Or date.plus(1)

previousDay = date - 1 // Or date.minus(1)

// ++ operator to move one day ahead.

dateNext++ // Or dateNext.next()

assert dateNext == nextDay

// -- operator to move one day back.

datePrevious-- // Or datePrevious.previous()

assert datePrevious == previousDay

otherDate = new Date().parse('yyyy/MM/dd', '1973/07/21')

// Dates can be used in ranges.

assert 12 == (otherDate..<date).size()

// Set Locale to assert date formatting.

Locale.setDefault(Locale.US)

Page 8: Groovy Goodness Notebook Sample

Dates 2

// Date.format() uses java.text.SimpleDateFormat.

assert '9 July, 1973' == date.format("d MMMM, yyyy")

assert '7/9/73' == date.getDateString()

Original blog post written on August 31, 2009

Setting Date and Calendar Values with Subscript Operators

In Groovy 1.7.3 we have some new ways to set the value of Date or Calendar objects. We can for exampleuse the subscript operators (getAt() and putAt() methods) to define values for fields or get the valuefrom a field. The fields are the Calendar constants like Calendar.YEAR, Calendar.DATE.

import static java.util.Calendar.*

def date = new Date()

// Set value with subscript operator

date[YEAR] = 2010

date[MONTH] = JUNE

date[DATE] = 14

assert 110 == date.year

assert 5 == date.month

assert 14 == date.date

// Get value with subscript operator

assert 2010 == date[YEAR]

assert JUNE == date[MONTH]

assert 14 == date[DATE]

def cal = Calendar.instance

// Set value with subscript operator

cal[YEAR] = 2000

cal[MONTH] = DECEMBER

cal[DATE] = 25

assert '2000-12-25' == cal.format('yyyy-MM-dd')

assert 2000 == cal[YEAR] // Get value with subscript operator

Original blog post written on June 14, 2010.

Convert Date to java.sql.Timestamp

Groovy adds many methods to standard Java classes we can use in our code. To convert a simple Dateobject to a java.sql.Timestamp we can simply use the toTimestamp() method on a Date object.

Page 9: Groovy Goodness Notebook Sample

Dates 3

import static java.util.Calendar.*

// Create date object with specific year, month and day.

def date = new Date()

date.clearTime()

date.set year: 2010, month: AUGUST, date: 10

// Convert to java.sql.Timestamp.

def sqlTimestamp = date.toTimestamp()

assert 'java.sql.Timestamp' == sqlTimestamp.class.name

assert '2010-08-10 00:00:00.0' == sqlTimestamp.toString()

Original blog post written on August 30, 2010.

Convert Date to Calendar

In Groovy version 1.7.6 we can convert a Date to a Calendar with the toCalendar() method. ThetoCalendar() method is added to the Date class by Groovy.

import static java.util.Calendar.*

def date = new Date()

date.set year: 2010, month: 11, date: 16

def calendar = date.toCalendar()

assert calendar[YEAR] == 2010

assert calendar[MONTH] == Calendar.DECEMBER

assert calendar[DATE] == 16

assert calendar.format('dd-MM-yyyy') == '16-12-2010'

assert calendar in Calendar

Original blog post written on December 16, 2010.

Format Dates with TimeZone

Since Groovy 1.8.3 we can use an extra TimeZone parameter with the format() method of the Date class.This can be used to print a date/time for a particular timezone.

Page 10: Groovy Goodness Notebook Sample

Dates 4

import static java.util.Calendar.*

def timeZone = TimeZone.getTimeZone('Europe/Amsterdam')

def otherTimeZone = TimeZone.getTimeZone('Australia/Canberra')

def cal = Calendar.instance

cal.set(year: 2011, month: OCTOBER, date: 20, hourOfDay: 12, minute: 30)

def date = cal.time

def dateFormat = 'yyyy/MM/dd HH:mm'

assert date.format(dateFormat, timeZone) == '2011/10/20 12:30'

assert date.format(dateFormat, otherTimeZone) == '2011/10/20 21:30'

Original blog post written on October 20, 2011.

Parse Date.toString() Value

With Groovy 1.8.4 we can parse the output of the Date.toString() method back to a Date with theparseToStringDate() method. For example we get the String value of a Date from an external sourceand want to parse it to a Date object. The format of the String must have the pattern “EEE MMM ddHH:mm:ss zzz yyyy” with the US Locale. This is used by the toString() method of the Date class.

import static java.util.Calendar.*

// Create date 10 November 2011.

def cal = Calendar.getInstance(TimeZone.getTimeZone('Europe/Amsterdam'))

def date = cal.time

date.clearTime()

date[YEAR] = 2011

date[MONTH] = NOVEMBER

date[DATE] = 10

// Get toString() value.

def dateToString = date.toString()

assert dateToString == 'Thu Nov 10 00:00:00 CET 2011'

// Replace Nov for Dec in string and 10 for 24.

dateString = dateToString.replace('Nov', 'Dec').replace('10', '24')

// Use parseToStringDate to get new Date.

def newDate = Date.parseToStringDate(dateString)

assert newDate[MONTH] == DECEMBER

assert newDate[DATE] == 24

assert newDate[YEAR] == 2011

Original blog post written on November 10, 2011.

Page 11: Groovy Goodness Notebook Sample

Dates 5

Use the set Method to Define a Date or Calendar Value

In a previous post we learned about the new subscript operator support in Groovy 1.7.3 for setting Date

or Calendar values. But we have other new ways in Groovy 1.7.3: we can use a set() method to set thevalues. The method accepts a Map with the following keys: year, month, date, hourOfDay, minute andsecond. The keys are used to set the according values of the Date or Calendar object.

import static java.util.Calendar.*

def cal = Calendar.instance

cal.set(year: 2010, month: JULY, date: 9)

assert 'Birthday @ 2010-7-9' == 'Birthday @ ' + cal.format('yyyy-M-d')

assert FRIDAY == cal[DAY_OF_WEEK]

def date = new Date()

date.set(hourOfDay: 12, minute: 0, second: 0, year: 2010, month: JUNE, date: 1)

assert '12:00:00' == date.format('HH:mm:ss')

assert 2010 == date[YEAR]

assert JUNE == date[MONTH]

assert 1 == date.getAt(DATE)

Original blog post written on June 14, 2010.

Create New Date from Old Date with Updates

Groovy 1.7.3 adds the updated() method to the Date and Calendar classes. We pass a Map as parameterto this method to define which fields are updated. The fields that are not mentioned are unchanged. Theresult is a new Date or Calendar object, our original object stays the same.

import static java.util.Calendar.*

def cal = Calendar.instance

cal[MONTH] = DECEMBER

def calNextMonth = cal.updated(month: cal[MONTH] + 1, year: 2012)

assert JANUARY == calNextMonth[MONTH]

assert 2013 == calNextMonth[YEAR]

def date = new Date()

date.set(year: 2011, month: MAY, date: 5)

def dateTenYearsAgo = date.updated(year: date[YEAR] - 10)

assert '2011-5-5' == date.format('yyyy-M-d')

assert '2001-5-5' == dateTenYearsAgo.format('yyyy-M-d')

Original blog post written on June 14, 2010.

Page 12: Groovy Goodness Notebook Sample

Dates 6

Create New Date or Calendar from Existing and Set Property Value

Since Groovy 2.2 we can create a new Date or Calendar object from an existing Date and Calendar

object and directly change property values. We must use the copyWith() method and we pass a mapwith property names and values as an argument. The newly created object will have the old values forproperties from the original object and the properties set in the map are overridden.

The following code shows the new copyWith() method:

import static java.util.Calendar.NOVEMBER

// Create original date.

def date = new Date().clearTime()

date.set(year: 2013, month: NOVEMBER, date: 18)

// Use copyWith to get new Date and

// immmediatelly set year to 2014.

def yearLater = date.copyWith(year: 2014)

assert yearLater.format('dd-MM-yyyy') == '18-11-2014'

// Also works for Calendar.

def cal = Calendar.instance

cal.set(year: 2013, month: NOVEMBER, date: 10)

// Create new Calendar with new date value.

def newCalendar = cal.copyWith(date: 18)

assert newCalendar.format('dd-MM-yyyy') == '18-11-2013'

Code written with Groovy 2.2.

Original blog post written on November 18, 2013.

Clear Time Portion of a Date

Working with dates in Groovy is easy. We get a lot of extra functionality compared to the standard JavaDate class. One of the extra methods added to the Date class since Groovy 1.6.8 is clearTime(). WithclearTime() we reset the time portion of a date to 12 o’clock midnight. This makes it easier to comparedates if we only are interested in the date, month, year parts.

Page 13: Groovy Goodness Notebook Sample

Dates 7

// Create new date.

def d = new Date(year: 2010, month: Calendar.JULY, date: 1,

hours: 7, minutes: 12, seconds: 0)

assert '7/1/10 7:12:00 AM' == d.dateTimeString

// Reset time portion of the date.

d.clearTime()

assert '7/1/10 12:00:00 AM' == d.dateTimeString

Original blog post written on July 1, 2010.

Date and Time Durations and the TimeCategory

Groovy has some elegant ways to work with date and time values. One of them is the support of durations.We can define a duration to denote a certain time amount, like 7 days, 2 hours and 50 minutes. We canuse these durations to add or subtract them from date and time objects.

The TimeCategory provides an even Groovier way to work with durations. We can use constructs like7.days + 12.minutes to create a duration. When we read this code it is just like reading English text.Here is some sample code:

import groovy.time.*

// Define period of 2 years, 3 months, 15 days, 0 hours,

// 23 minutes, 2 seconds and 0 milliseconds.

def period = new DatumDependentDuration(2, 3, 15, 0, 23, 2, 0)

assert '2 years, 3 months, 15 days, 23 minutes, 2.000 seconds' ==

period.toString()

def year2000 = new Date(100, 0, 0) // Jan 1, 2000

assert '14 Apr 2002 22:23:02 GMT' == (period + year2000).toGMTString()

// Define time period of 5 hours, 54 minutes and 30 milliseconds.

def time = new TimeDuration(5, 54, 0, 30)

assert '5 hours, 54 minutes, 0.030 seconds' == time.toString()

use (TimeCategory) {

assert period.toString() == (2.years + 3.months + 15.days +

0.hour + 23.minutes + 2.seconds)

.toString()

assert time.toString() == (5.hours + 54.minutes + 30.milliseconds)

.toString()

// We can use period.from.now syntax.

def d1 = 1.week - 1.day

def d2 = new Date() + 6.days

Page 14: Groovy Goodness Notebook Sample

Dates 8

assert d2.format('yyyy-MM-dd') == d1.from.now.toString()

// We can use period.ago syntax.

def d3 = 3.days.ago

def d4 = new Date() - 3

assert d4.format('yyyy-MM-dd') == d3.toString()

}

Original blog post written on September 2, 2009

Loop Through Date and Calendar Ranges

Groovy already adds a lot of extra methods to the Date and Calendar classes. And since Groovy 2.2 we canuse the upto() method and loop over a begin date up to another date. We pass a closure that is executedfor each day. We can also iterate back using the downto() method.

// We can loop from today

// to nextWeek and invoke a closure for each day.

def today = new Date().clearTime()

def nextWeek = today + 7

today.upto(nextWeek) {

// Print day of the week.

println it.format('EEEE')

}

println()

nextweek.downto(today) {

prinltn it.format('EEEE')

}

When we run the code we get the following output:

Monday

Tuesday

Wednesday

Thursday

Friday

Saturday

Sunday

Monday

Monday

Sunday

Saturday

Friday

Page 15: Groovy Goodness Notebook Sample

Dates 9

Thursday

Wednesday

Tuesday

Monday

In the next sample we use the upto() method on the Calendar class:

// upto() also works on Calendar objects.

def to = Calendar.instance

to.set(year: 2013, month: Calendar.NOVEMBER, date: 18)

def from = Calendar.instance

from.set(year: 2013, month: Calendar.NOVEMBER, date: 13)

from.upto(to) {

if (it[Calendar.DATE] % 2 == 0) {

print 'Even'

} else {

print 'Odd'

}

println ' date'

}

We get the following output:

Odd date

Even date

Odd date

Even date

Odd date

Even date

Code written with Groovy 2.2.

Original blog post written on November 18, 2013.

Page 16: Groovy Goodness Notebook Sample

Maps

Check if Maps are Equal

With Groovy 1.8 the equals()method is added to Map. This means we can check if maps are equals. Theyare equals if both maps have the same size, and keys and values are the same.

def map1 = [user: 'mrhaki', likes: 'Groovy', age: 37]

def map2 = [age: 37.0, likes: 'Groovy', user: 'mrhaki']

def map3 = [user: 'Hubert Klein Ikkink', likes: 'Groovy']

assert map1.equals(map2)

assert map1 == map2

assert !map1.equals(map3)

assert map2 != map3

Original blog post written on April 27, 2011.

Sorting a Map

Maps don’t have an order for the elements, but we may want to sort the entries in the map. Since Groovy1.7.2 we can use the sort()method which uses the natural ordering of the keys to sort the entries. Or wecan pass a Comparator to the sort() method to define our own sorting algorithm for the keys.

def m = [sort: 'asc', name: 'test', paginate: true, max: 100]

def expectedKeys = ['max', 'name', 'paginate', 'sort']

// Since 1.7.2

assert expectedKeys == m.sort()*.key

// Since 1.7.2

assert expectedKeys == m.sort( { k1, k2 -> k1 <=> k2 } as Comparator )*.key

// Sorting before Groovy 1.7.2

assert expectedKeys == new TreeMap(m)*.key

// Sort by closure.

assert expectedKeys == m.sort { e1, e2 -> e1.key <=> e2.key }*.key

Original blog post written on April 20, 2010.

Page 17: Groovy Goodness Notebook Sample

Maps 11

Turn a List into a Map

With Groovy we can use the values of an Object array and transform them to a map with thetoSpreadMap() method. The array must have an even number of elements, because the odd elementsare the keys for the new map and the even numbers are the values for the keys. The SpreadMap object,which now contains the keys and values, is an immutable map, so we cannot change the contents oncewe have created the map.

def list = ['key', 'value', 'name', 'mrhaki'] as Object[]

def map = list.toSpreadMap()

assert 2 == map.size()

assert 'value' == map.key

assert 'mrhaki' == map['name']

Original blog post written on January 4, 2010.

Complex Keys in Maps

In Groovy we can use non-string keys for maps. We only have to place parenthesis around the key tomake it work. This way we can use variables and types like Date and Boolean as keys for our map. Whenwe use parenthesis around the key when using the . notation the key is converted to a String, otherwisethe key is not converted and keeps it type.

def key = 100 // Variable to be used a key.

def m = [

(new Date(109, 11, 1)): 'date key',

(-42): 'negative number key',

(false): 'boolean key',

(key): 'variable key'

]

m.(true) = 'boolean key' // Key is converted to String.

m.(2 + 2) = 'number key'

m[(key + 1)] = 'number key' // Key keeps to be Integer.

assert 'date key' == m[new Date(109, 11, 1)]

assert 'negative number key' == m.get(-42)

assert 'boolean key' == m[(false)]

assert 'variable key' == m[100]

assert 'variable key' == m.getAt(key)

// Key is String so we can use it to get the value.

assert 'boolean key' == m['true']

assert 'number key' == m.'4'

assert 'number key' == m.get(101)

Original blog post written on November 7, 2009

Page 18: Groovy Goodness Notebook Sample

Maps 12

Use inject Method on a Map

The inject() method is since Groovy 1.8.1 also available for Map objects. The closure argumentsaccepts two or three arguments. With the three-argument variant we get the key and value separatelyas arguments. Otherwise we get a map entry as closure argument.

// 3-argument closure with key, value.

def m = [user: 'mrhaki', likes: 'Groovy']

def sentence = m.inject('Message: ') { s, k, v ->

s += "${k == 'likes' ? 'loves' : k} $v "

}

assert sentence.trim() == 'Message: user mrhaki loves Groovy'

// 2-argument closure with entry.

def map = [sort: 'name', order: 'desc']

def equalSizeKeyValue = map.inject([]) { list, entry ->

list << (entry.key.size() == entry.value.size())

}

assert equalSizeKeyValue == [true, false]

Original blog post written on September 27, 2011.

Intersect Maps

Since Groovy 1.7.4 we can intersect two maps and get a resulting map with only the entries found in bothmaps.

def m1 = [a: 'Groovy', b: 'rocks', c: '!']

def m2 = [a: 'Groovy', b: 'rocks', c: '?', d: 'Yes!']

assert [a: 'Groovy', b: 'rocks'] == m1.intersect(m2)

assert [1: 1.0, 2: 2] == [1: 1.0, 2: 2].intersect([1: 1, 2: 2.0])

Original blog post written on August 9, 2010.

Subtracting Map Entries

Groovy 1.7.4 adds the minus() method to the Map class. The result is a new map with the entries of themap minus the same entries from the second map.

Page 19: Groovy Goodness Notebook Sample

Maps 13

def m1 = [user: 'mrhaki', age: 37]

def m2 = [user: 'mrhaki', name: 'Hubert']

def m3 = [user: 'Hubert', age: 37]

assert [age: 37] == m1 - m2

assert [user: 'mrhaki'] == m1 - m3

Original blog post written on August 9, 2010.

Process Map Entries in Reverse

Since Groovy 1.7.2 we can loop through a Map in reverse with the reverseEach(). The order in which thecontent is processed is not guaranteed with a Map. If we use a TreeMap the natural ordering of the keys ofthe map is used.

def reversed = [:]

[a: 1, c: 3, b: 2].reverseEach { key, value ->

reversed[key] = value ** 2

}

assert [b: 4, c: 9, a: 1] == reversed

// TreeMap uses natural ordering of keys, so

// reverseEach starts with key 'c'.

def tree = [a: 10, c: 30, b: 20] as TreeMap

def reversedMap = [:]

tree.reverseEach {

reversedMap[it.key] = it.value * 2

}

assert [c: 60, b: 40, a: 20] == reversedMap

Original blog post written on August 24, 2010.

Getting a Submap from a Map

To get only a subset of a map we can use the subMap() method. We provide a list of keys as parameter todefine which elements from the map we want returned.

Page 20: Groovy Goodness Notebook Sample

Maps 14

def map = [name: 'mrhaki', country: 'The Netherlands',

blog: true, languages: ['Groovy', 'Java']]

def keys = ['name', 'blog']

assert [name: 'mrhaki', blog: true] == map.subMap(keys)

def booleanKeys = map.findAll { it.value instanceof Boolean }

.collect { it.key }

assert [blog: true] == map.subMap(booleanKeys)

def words = ['a': 'Apple', 'j': 'Java', 'g': 'Groovy', 'c': 'Cool']

def range = 'c'..'h' // Range is also a list and can be used here.

def rangeWords = words.subMap(range).findAll{ it.value }

// words.subMap(range) returns [c:Cool, d:null, e:null,

// f:null, g:Groovy, h:null]

// so we use the findAll method to filter out all null values.

assert ['c': 'Cool', 'g': 'Groovy'] == rangeWords

Original blog post written on October 29, 2009

Grouping Map Elements

In a previous post we learned how to use the groupBy() method on collections. The Map class has anextra method: groupEntriesBy(). We must provide a closure for this method to define how we want theelements of the map to be grouped. The result is a new Map with keys and a list of Map$Entry objects foreach key. This is different from the result of the groupBy() method. Because then we get a Map with keysand a Map for each key.

// A simple map.

def m = [q1: 'Groovy', sort: 'desc', q2: 'Grails']

// Closure we use to define the grouping.

// We want all keys starting with 'q' grouped together

// with the key 'params', all other keys are not grouped.

def groupIt = { key, value ->

if (key.startsWith('q')) {

'params'

} else {

key

}

}

// Use groupEntriesBy.

def groupEntries = m.groupEntriesBy(groupIt)

assert 2 == groupEntries.size()

assert groupEntries.params

assert groupEntries.sort

Page 21: Groovy Goodness Notebook Sample

Maps 15

// Key for a list of Map$Entry objects.

assert 'desc' == groupEntries.sort[0].value

assert 2 == groupEntries.params.size()

assert 'Groovy' == groupEntries.params[0].value

assert 'q1' == groupEntries.params[0].key

assert 'Grails' == groupEntries.params.find { it.key == 'q2' }.value

assert groupEntries.params instanceof ArrayList

assert groupEntries.params[0] instanceof Map$Entry

// Use groupBy.

def group = m.groupBy(groupIt)

assert 2 == group.size()

assert group.params

assert group.sort

// Key for Map with key/value pairs.

assert 'desc' == group.sort.sort

assert 2 == group.params.size()

assert 'Groovy' == group.params.q1

assert 'q1' == group.params.keySet().toArray()[0]

assert 'Grails' == group.params.q2

assert group.params instanceof Map

assert group.params.q1 instanceof String

Original blog post written on October 14, 2009

Get Value from Map or a Default Value

The get() method in the Groovy enhanced Map interface accepts two parameters. The first parameter isthe name of the key we want to get a value for. And the second parameter is the default value if there isno value for the key.

// Simple map.

def m = [name: 'mrhaki', language: 'Groovy']

assert 'mrhaki' == m.getAt('name')

assert 'mrhaki' == m['name']

assert 'Groovy' == m.language

assert 'mrhaki' == m."name"

assert 'mrhaki' == m.get('name') // We can omit the default value if we know the key e\

xists.

assert 'Groovy' == m.get('language', 'Java')

assert null == m.get('expression') // Non-existing key in map.

assert 'rocks' == m.get('expression', 'rocks') // Use default value, this also creates\

the key/value pair in the map.

assert 'rocks' == m.get('expression')

assert [name: 'mrhaki', language: 'Groovy', expression: 'rocks'] == m

Original blog post written on November 3, 2009

Page 22: Groovy Goodness Notebook Sample

Maps 16

Map with Default Values

In Groovy we can create a map and use the withDefault()method with a closure to define default valuesfor keys that are not yet in the map. The value for the key is then added to the map, so next time we canget the value from the map.

def m = [start: 'one'].withDefault { key ->

key.isNumber() ? 42 : 'Groovy rocks!'

}

assert 'one' == m.start

assert 42 == m['1']

assert 'Groovy rocks!' == m['I say']

assert 3 == m.size()

// We can still assign our own values to keys of course:

m['mrhaki'] = 'Hubert Klein Ikkink'

assert 'Hubert Klein Ikkink' == m.mrhaki

assert 4 == m.size()

Original blog post written on July 14, 2010.

Determine Min and Max Entries in a Map

Since Groovy 1.7.6 we can use the min() and max() methods on a Map. We use a closure to define thecondition for a minimum or maximum value. If we use two parameters in the closure we must do aclassic comparison. We return a negative value if the first parameter is less than the second, zero if theyare equal, or a positive value if the first parameter is greater than the second parameter. If we use a singleparameter we can return a value that is used as Comparable for determining the maximum or minimumentry in the Map.

def money = [cents: 5, dime: 2, quarter: 3]

// Determine max entry.

assert money.max { it.value }.value == 5

// Use String comparison for key.

assert money.max { it.key }.key == 'quarter'

// Use Comparator and compare key size.

assert money.max { a, b ->

a.key.size() <=> b.key.size()

}.key == 'quarter'

// Determine min entry.

assert money.min { it.value }.value == 2

Page 23: Groovy Goodness Notebook Sample

Maps 17

// Use String comparison for key.

assert money.min { it.key }.key == 'cents'

// Use Comparator and compare key size.

assert money.min { a, b ->

a.key.size() <=> b.key.size()

}.key == 'dime'

Original blog post written on December 16, 2010.


Recommended