Collections

We assume you have basic knowledge on Java Collection Framework (JCF), so we are not going to discuss the fundamentals of the collection framework. We start on what Groovy provides on collection framework and frequently used utility methods provided by different collection objects.

Groovy supports different collective data types to store group of objects, such as range, lists, sets, and maps. If you are already a Java programmer, you will find how easy it is in Groovy to play with collective data types as compared to Java. Apart from sets, lists, and maps, Groovy has introduced ranges, which was not available in Java.

Set

A set is an unordered collection of objects, with no duplicates. It can be considered as an unordered list with restrictions on uniqueness, and is often constructed from a list. Set can also contain at most one null element. As implied by its name, this interface models the mathematical set abstraction.

The following code snippet explains how to create a Set. Elements can be added or removed from the Set using the add, addAll, remove, or removeAll methods.

You might have learned a lot about Set in your math classes, where the instructor teaches you different set operations, such as union and intersection. Groovy also provides similar functionalities. The union of two sets contains all the unique elements and common elements present in both the sets without repetition. The intersection finds common elements between the two sets. The complement of Set1 and Set2 will contain all those elements of Set1 that are not present in Set2.

Let's take a look at the following code:

// Creating a Set
def Set1 = [1,2,1,4,5,9] as Set
Set Set2 = new HashSet( ['a','b','c','d'] )

// Modifying a Set
Set2.add(1)
Set2.add(9)
Set2.addAll([4,5])        // Set2: [1, d, 4, b, 5, c, a, 9]

Set2.remove(1)        
Set2.removeAll([4,5])    // Set2: [d, b, c, a, 9]

// Union of Set
Set Union = Set1 + Set2     // Union: [1, 2, 4, 5, 9, d, b, c, a]

// Intersection of Set
Set intersection = Set1.intersect(Set2)    // Intersection: [9]

// Complement of Set
Set Complement = Union.minus(Set1)    // Complement: [d, b, c, a]

List

As compared to Set, a List is an ordered collection of objects, and a List can contain duplicate elements. A List can be created using List list = [], which creates an empty list that is an implementation of java.util.ArrayList.

The following code snippet shows how to create a List, read values from the list, and list some utility methods on the List:

// Creating a List
 def list1 = ['a', 'b', 'c', 'd']
 def list2 = [3, 2, 1, 4, 5] as List

// Reading a List
println list1[1]          // Output: b
println list2.get(4)      // Output: 5
println list1.get(5)      //Throws IndexOutOfBoundsException

// Some utility method on List
//Sort a List
println list2.sort()      // Output: [1, 2, 3, 4, 5]
// Reserve a list
println list1.reverse()      // Output: [d, c, b, a]
// Finding elements
println ("Max:" + list2.max() + ":Last:" + list1.last())   
// Output: Max:5:Last:d

Some of the List methods accept Closure. The following example shows how to find the first even number using the find method, and list of all the even numbers using the findAll method:

println list2.find({ it %2 == 0})    // Output: 2
println list2.findAll({it %2 == 0})  // Output: [2, 4]

Do not get confused by the "it" keyword inside the curly brackets. We will discuss this in the Closure section.

Map

Map is a key-value pair collection, where the key is unique. In Groovy, key-value pairs are delimited by colons. An empty Map can be created via [:]. By default, a Map is of the type java.util.HashMap. If the keys are of type String, you can avoid the single or double quotes in the Map declaration. For example, if you want to create a Map with name as the key and Groovy as the value, you can use the following notation:

Map m1 = [name:"Groovy"]

Here, [name: "Groovy"] is the same as ["name":"Groovy"]. By default, Map keys are Strings. But if you want to put some variable as the key, then use parentheses, as shown in the following code:

String s1 = "name"
Map m1 = [(s1):"Groovy"]

Alternatively, you can create a Map in the following way:

def m2 = [id:1,title: "Mastering Groovy" ] as Map

You can get the objects from the Map using key m2.get("id") or m2["id"].

Tip

If key is a String, then to get a value, you need to specify the key in double quotes (""). If you do not specify the key in double quotes, it will treat it as a variable name and will try to resolve it.

Now we will discuss some of the utility methods (each, any, and every) of Maps, which accept Closures:

Map ageMap = [John:24, Meera:28,Kat:31,Lee:19,Harry:18]

To parse every entry of Map, you can use each. It takes either entry or key-value as a parameter, as shown in the following table:

ageMap.each {key, value ->
  println "Name is "+key
  println "Age is " + value
}

ageMap.each {entry  ->
  println "Name is "+entry.key
  println "Age is " + entry.value
}

If you want to validate the Map data, you can use either .every or .any, based on your requirements. The .every method checks and makes sure all records fulfil the mentioned condition, while .any just checks whether any one record fulfils the condition. For example, if you want to check whether there is any user who is more than 25 years old:

ageMap.any {entry -> entry.value > 25 }

It returns the output as a Boolean value; in this case, true, as Meera is 28.

If you want to check whether all the users are above 18:

ageMap.every {entry -> entry.value > 18 }

It will return false, as Harry is 18.

You can also use the find and findAll methods for Map in the same pattern as we used for List in the List section.

Range

Apart from Java collection types, Groovy also supports a new collective data type Range. It is defined as two values (generally starting point and ending point) separated by two dots.

To create a Range, use the following code:

def range1 = 1..10
Range range2 = 'a'..'e'

To read values from Range, use the following code:

range1.each { println it }

You can also use the .any and .every operators to validate range for your specific requirement. It checks for the condition and returns a Boolean value. Let's take a look at the following code:

range1.any { it > 5 }
range1.every { it > 0 }

For modifying the range interval, use the following code. If you want to modify range interval from default 1 to any other number, you can set it via step method. It returns a list:

List l1 = range1.step(2)    //Output: [1, 3, 5, 7, 9]

To fetch the starting element and ending element of a range, use the From and To element, as shown in the following code:

range1.getFrom()      //Output: 1
range1.getTo()        //Output: 10

The isReverse() method is used to check the range trend to see whether the range is constructed using to value ( higher value) to from value (lower value):

range1.isReverse()       // Output: false
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.51.145