Groovy Dictionary Example
In this article we will see how to have a Dictionary in Groovy
. Groovy does not have a built in dictionary like Python
language. However we can use the Map
data structure for manipulating a Dictionary.
To understand this article, the reader should have a better understanding of how Map works in Groovy. You can read this Groovy-Map-Example for the same.
The following table shows an overview of the entire article:
Table of Contents
1. Environment
The examples shown below are executed in the Command Prompt / Shell. But they are guaranteed to work with any of the IDEs (like Eclipse, IntelliJ IDEA, Netbeans) through the respective plugins. The examples are executed with the Groovy Version Groovy Version: 2.4.3.
2. Concept behind Dictionary
Ideally a Dictionary is a Collection of things being stored under a key-value pair and that can be retrieved quickly anytime on demand. Though we would achieve the Dictionary via a Map, we need to have few boundaries set.
A Map will allow a null key or value to be set in the collection. However a dictionary is not supposed to have a null key or value, which otherwise will defeat its purpose. Hence, we will have to restrict the same in our Groovy code.
As far as the key/value pairs are concerned, they can be any valid identifiers and the objects. However if you are putting an Object of a custom class (your implementation) as a value, you need to ensure the equals()
and hashCode()
methods are implemented appropriately, as it is still based on Java Map Interface which works on Hashing. The good implementation of these two methods will guarantee an efficient and collision-free manipulation of key-value in the collection.
3. Examples
We will see two different examples in this article.
- Custom Dictionary – Illustration
- Country Captial Dictionary – Realistic Example
3.1. Custom Dictionary – Illustration
In this example, let us have a custom class to facilitate a Dictionary with the validations in place to ensure there are no null key/values added. It is mandatory otherwise the Map
interface will allow the null key / value by default. As explained above, this will only ensure the right implementation of a Dictionary.
GroovyCustomDictionary.groovy
package com.javacodegeeks.example.groovy.util; def scriptSimpleName = this.class.getSimpleName() println "================================================== " println "Output of Script : " + scriptSimpleName println "Executed at : " + new java.util.Date() println "================================================== " println " " class Dictionary { def key def value def dict = [:] // Empty No-arg constructor. Required for the overloaded constructor below Dictionary() {} // A two-arg constructor to facilitate an entry to be added during instantiation Dictionary(key, value) { put(key,value) } // Method to validate the key, value inputs for not-null def validate(key, value) { if(key==null) throw new RuntimeException("Null key is not permitted") if(value==null) throw new RuntimeException("Null value is not permitted") } // Actual method to store the key-value pairs. // Exception message printed if any of them is null. def put(key, value) { try { validate(key,value) this.dict[key]=value printInfo() } catch(Exception exception) { println " #### ERROR #### --> " + exception.getMessage() println " " } } // Overridden toString() to have a meaningful display String toString() { "[Dictionary] hashCode = ${this.hashCode()}, Dict : ${dict}" } // Utility method for printing the information def printInfo() { println "myDict Custom Object : ${this}" println " " } } def myDictObj = new Dictionary() println " ==> 1. Initial Empty Dictionary ..." myDictObj.printInfo() println " ==> 2. Attempting to Store values ... " myDictObj.put('name', 'Sam') myDictObj.put('age', 14) println " ==> 3. Attempting to store Null Key ... " myDictObj.put(null, 'NotNullValue'); println " ==> 4. Attempting to store Null value ... " myDictObj.put("NullKey",null); println " ==> 5. Attempting with duplicate key (value will be replaced) ... " myDictObj.put('name', 'Samuel') println " " println " ---------------- END OF SCRIPT EXECUTION -------------------- " println " "
The above script produces the following output.
================================================== Output of Script : GroovyCustomDictionary Executed at : Thu Mar 24 23:39:02 IST 2016 ================================================== ==> 1. Initial Empty Dictionary ... myDict Custom Object : [Dictionary] hashCode = 1300638095, Dict : [:] ==> 2. Attempting to Store values ... myDict Custom Object : [Dictionary] hashCode = 1300638095, Dict : [name:Sam] myDict Custom Object : [Dictionary] hashCode = 1300638095, Dict : [name:Sam, age:14] ==> 3. Attempting to store Null Key ... #### ERROR #### --> Null key is not permitted ==> 4. Attempting to store Null value ... #### ERROR #### --> Null value is not permitted ==> 5. Attempting with duplicate key (value will be replaced) ... myDict Custom Object : [Dictionary] hashCode = 1300638095, Dict : [name:Samuel, age:14] ---------------- END OF SCRIPT EXECUTION --------------------
3.2. Country Captial Dictionary – Realistic Example
In this example, we will load the inputs from a text file country-capital.txt
which has got a few countries and their capitals in each line as a comma separated value. We will load this text file and create a Dictionary (Map) at runtime.
The country-capital.txt file has the following contents (for simplicity, only few lines of the file is shown below).
GroovyCountryCapitalDictionary.groovy
# Ref URL : https://www.countries-ofthe-world.com/capitals-of-the-world.html Afghanishtan, Kabul Australia, Canberra Austria, Vienna Bahamas, Nassau Bahrain, Manama
The following example shows the pattern of how a Dictionary can be used in a real world as follows.
- A Dictionary is created with the fixed set of inputs parsed out of a text file (by excluding comments and blank lines)
- Inputs are validated for not being NULL before getting added into the Dictionary Collection
-
Program is executed in a Command line with two different options – 1. Print the Dictionary Contents 2. Get the country or capital
matching with the input passed in the command line - Program warns and assists the user with the Usage Information if the arguments are inappropriate
- Program does NOT facilitate addition/removal of entries to and from Dictionary.
GroovyCountryCapitalDictionary.groovy
package com.javacodegeeks.example.groovy.util; def file = new File('country-capital.txt') //println file.getAbsolutePath() def validLines = [] file.each { line -> if(line.trim().length()>0 && !line.startsWith("#")) validLines.add(line) } def dict = [:] def key, value def tokens validLines.each { line -> tokens = line.tokenize(",") key = tokens[0].trim() value = tokens[1].trim() validate(key,value) dict[key]=value } /* Method to validate the key, value inputs for not-null */ def validate(key, value) { if(key==null) throw new RuntimeException("Null key is not permitted") if(value==null) throw new RuntimeException("Null value is not permitted") } def getCountryStartsWith = { String s -> def result = [] dict.keySet().each { if(it.startsWith(s)) result.add(it) } result } def getCapitalStartsWith = { String s -> def result = [] dict.values().each { if(it.startsWith(s)) result.add(it) } result } def printUsage() { def scriptName = this.class.getSimpleName() println "" println "[Usage] Please use any of the following : " println " 1. $scriptName <[Country:] [Capital:]" println " 2. $scriptName print --> to print the dictionary" System.exit(1) } def handleInvalidArgs() { println " " println " ## Please specify the input in proper format" printUsage() } if(args.length<1) { printUsage() } if(args[0].equalsIgnoreCase("print")) { println " " println "Total Elements in Dictionary : " + dict.size() println " " println " Dictionary Contents " println "---------------------------" println dict System.exit(0) } else { def argType def argTokens def inputArg = args[0] argTokens = args[0].tokenize(':') if(argTokens.size()<2) { handleInvalidArgs() } argType = argTokens[0] if(argType.equalsIgnoreCase("country")) { def countryAlphabet = argTokens[1] println "" println "Country starts with '${countryAlphabet}' : " println getCountryStartsWith("${countryAlphabet}") } else if(argType.equalsIgnoreCase("capital")) { def capitalAlphabet = argTokens[1] println "" println "Capital starts with '${capitalAlphabet}' : " println getCapitalStartsWith("${capitalAlphabet}") } else { handleInvalidArgs() } }
The above script produces the following output when simply executed without any arguments. The output displayed will be the Usage information with the format.
[Usage] Please use any of the following : 1. GroovyCountryCapitalDictionary <[Country:] [Capital:] 2. GroovyCountryCapitalDictionary print --> to print the dictionary
When you specify the starting alphabet(s) of a Country that you are looking for, the program displays the output with the countries matching with the characters/alphabets specified in the command line.
groovy GroovyCountryCapitalDictionary.groovy Country:I Country starts with 'I' : [India, Indonesia, Ireland, Italy]
You can also specify the alphabet(s) for the Capital, as follows.
groovy GroovyCountryCapitalDictionary.groovy Capital:A Capital starts with 'A' : [Athens, Amsterdam, Ankara, Abu Dhabi]
If the input pattern is wrong, the program displays the Usage information to give a correct input next time. Note that the below invocation of the program does NOT have the starting alphabet, which is purposefully omitted.
groovy GroovyCountryCapitalDictionary.groovy Country: ## Please specify the input in proper format [Usage] Please use any of the following : 1. GroovyCountryCapitalDictionary <[Country:] [Capital:] 2. GroovyCountryCapitalDictionary print --> to print the dictionary
Hope you found this example series helpful in manipulating the Dictionary in Groovy. For the real scenarios, you are requested to add more validations and testing to keep the logic appropriate.
4. References
You may please refer the following URLs for further reading.
5. Download the Source Code
This is an example of how to manipulate a Dictionary in Groovy, tested with the Command Prompt / Shell against Groovy Version 2.4.3.
You can download the full source code of this example here: Groovy Dictionary Example