Groovy

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:

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.

  1. Custom Dictionary – Illustration
  2. 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.

  1. Groovy Map Example from Java Code Geeks Example
  2. Javadoc for Map Interface
  3. GroovyMap API Javadoc

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.

Download
You can download the full source code of this example here: Groovy Dictionary Example

Raghavan Muthu

Raghavan alias Saravanan Muthu is a seasoned IT professional having more than 2 decades of experience on Java SE/EE based Application Architecture, Design, Development, Management and Administration for Banking, Insurance, Telecom, HealthCare and Automobile Industries, having a very good hands on experience on Multi-threaded, batch processing applications and Relational Databases. He is currently working as a Director of Engineering for one of the Product based companies in India that delivers the product on Health Care and Insurance Domain. He holds a Post Graduation (Master of Science), and a PG Degree on Big Data Engineering from Birla Institute of Technology and Science (BITS), Pilani, India. He is a Founder, Chief Executive Volunteer and a Web Master of a non-profit charity organization named SHaDE (http://shade.org.in).
Subscribe
Notify of
guest

This site uses Akismet to reduce spam. Learn how your comment data is processed.

0 Comments
Inline Feedbacks
View all comments
Back to top button