Groovy Collections Example
1. Introduction
Apache Groovy (Groovy) is an object-oriented dynamic programming language for the Java platform. It is dynamically compiled to the Java Virtual Machine (JVM) bytecode, and inter-operates with other Java source codes and libraries. Groovy is written in Java and was first released in 2007.
Groovy provides native support for various collection types, including lists, sets, maps, and ranges. Most of these are based on the Java collection types and decorated with additional methods found in the Groovy development kit.
In this example, I will demonstrate how to use Groovy Collection interface to search, iterate, convert, and manipulate the elements in a collection.
2. Technologies Used
The example code in this article was built and run using:
- Java 1.8.101 (1.8.x will do fine)
- Maven 3.3.9 (3.3.x will do fine)
- Eclipse Mars (Any Java IDE would work)
- Groovy 2.4
3. Maven Project
A collection is an object that groups multiple elements into a single unit. It can be used to store, manipulate, retrieve, and communicate data. In this example, we will build unit test classes to demonstrate how to find, sort, split, and group elements.
3.1 Dependencies
We will add Groovy dependency in the pom.xml.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>jcg-zheng-demo</groupId> <version>1.0.0-SNAPSHOT</version> <artifactId>groovy-demo</artifactId> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.3</version> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.13</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>
3.2 Searching
Groovy Collection interface defines several searching methods:
find()– finds the first item matching the IDENTITY closurefind{Closure}– finds the first item matching the closure conditionfindAll()– finds all items matching the IDENTITY closurefindAll{Closure}– finds all items matching the closure conditionfindResult{Closure}– finds the first non-null result matching the closure conditionfindResult{Object, Closure}– finds the first non-null result matching the closure condition with a default resultgrep()– finds all elements which satisfies Groovy truthgrep(Object)– finds all elements that matches the given filter
In this step, we will create a groovy unit test class Demo_Find to show how to find desired items in a List, Set, Map, or Range.
Demo_Find.groovy
package jcg.zheng.demo.groovy
import static org.junit.Assert.*
import org.junit.Test
class Demo_Find {
@Test
public void find_element_from_array_with_matching_value(){
String[] names = ["Mary", "Becky", "Susan", "Tom"]
String foundByName = names.find { it.equalsIgnoreCase("mary") }
assertEquals("Mary", foundByName)
}
@Test
public void find_element_from_map_with_matching_key(){
def mymap = [name:"Mary", likes:"coding", id:1, comment:"Fun to hang out"]
def likesValue = mymap.find{ it.key == "likes" }.value
assertEquals("coding", likesValue)
println likesValue
}
@Test
public void find_element_from_list_with_matching_value(){
List names = ["Mary", "Becky", "Susan", "Tom"]
String foundByName = names.find { it.equalsIgnoreCase("mary")}
assertEquals("Mary", foundByName)
}
@Test
public void find_person_from_array_with_matching_firstName(){
Person [] persons = [new Person("Mary", "Zheng"), new Person("Alex", "Zheng"), new Person("Allen", "Zheng")]
Person found = persons.find { it.firstName == "Mary"}
assertEquals("Mary", found.firstName)
assertEquals("Zheng", found.lastName)
}
@Test
public void find_evenNumbers_from_range_use_containAll_to_verify(){
def numbers = (1..10)
List evenNumbers = numbers.findAll {it % 2 == 0}
print evenNumbers
List evenNumberUnderTen = [2, 4, 6, 8, 10]
assertTrue(evenNumberUnderTen.containsAll(evenNumbers))
}
@Test
public void findResults_from_list_with_matching_condition(){
List names = ["Mary", "Becky", "Susan", "Tom"]
String foundByName = names.findResult { if (it.startsWith("B")) it.toUpperCase()}
assertEquals("BECKY", foundByName)
}
@Test
public void grep_from_set_with_verify_with_equals(){
Set names = new HashSet()
names.add("Zhang")
names.add("Mary")
names.add("Mary")
names.add("Zheng")
Set foundNameWithH = names.grep{it.contains("h")}
assertEquals(2, foundNameWithH.size())
def hnames = ["Zhang", "Zheng"] as Set
assertTrue(foundNameWithH.equals(hnames))
println foundNameWithH
}
@Test
public void grep_object_from_set(){
Set mySet = [10, 20, 0, false, true, 'hello', [1, 2], [3, 4], null, "world"]
println mySet.grep(Number)
println mySet.grep(String)
println mySet.grep(Boolean)
println mySet.grep(Collection)
println mySet.grep('hello')
}
}
3.3 Iteration
Groovy Collection interface defines looping methods:
collect()– iterates through the collection transforming each element into new value withClosure.IDENTITYcollect(Closure transform)– iterates through the collection transforming each element into new value using closurecollect(Collection collector, Closure transform)– iterates through the collection transforming each element into new value using closure and adding it to the suppliedcollector.each– iterates through the collection, passing each item to the given closure. Please check out my other article for a demonstration ofeachmethod.
In this step, we will create a groovy unit test class Demo_Loop to show how to iterate a collection of List and Range.
Demo_Loop.groovy
package jcg.zheng.demo.groovy
import static org.junit.Assert.*
import org.junit.Test
class Demo_Loop {
@Test
public void loop_each_range_with_print(){
def numbers = (1..10)
numbers.each { println it }
}
@Test
public void loop_eachWithIndex_range_with_print(){
def numbers = (1..10)
numbers.eachWithIndex { number, i -> println "${i} = ${number}"}
}
@Test
public void when_collect_it_returns_new_collection_with_closure(){
def fruits = ["Banana", "Apple", "Grape", "Pear"]
List upperCaseFruits = fruits.collect { it.toUpperCase() }
assertEquals("BANANA", upperCaseFruits.get(0))
assertEquals("APPLE", upperCaseFruits.get(1))
assertEquals("GRAPE", upperCaseFruits.get(2))
assertEquals("PEAR", upperCaseFruits.get(3))
println upperCaseFruits
}
@Test
public void when_collect_with_default_it_returns_new_collection_with_closure(){
def initialFruits = ["ORANGE", "LEMON"]
def fruits = ["Banana", "Apple", "Grape", "Berry"]
def totalFruits = fruits.collect(initialFruits, { it.toUpperCase() })
println totalFruits //[ORANGE, LEMON, BANANA, APPLE, GRAPE, BERRY]
}
}
3.4 Convert
Groovy Collection and Iterable interfaces define several converting methods:
toSet()– convert a Collection to a SettoList()– convert anIterableto a ListtoArray()– returns an array with all the elements in this collection in the same sequence ordertoSpreadMap()– creates a spreadable map from thisIterableobject
In this step, we will create a groovy unit test class Demo_Convert to show how to convert a collection as List and Set.
Demo_Convert.groovy
package jcg.zheng.demo.groovy
import static org.junit.Assert.*
import org.junit.Test
class Demo_Convert {
@Test
public void convert_from_List_to_Set_duplicate_element_is_gone(){
List names = ["Mary", "Becky", "Susan", "Tom", "Mary"]
assertEquals(5, names.size())
Set nameSet = names.toSet()
assertEquals(4, nameSet.size())
println nameSet
}
@Test
public void convert_from_List_to_String(){
List names = ["Mary", "Becky", "Susan", "Tom"]
String nameValues = names.toListString()
assertEquals("[Mary, Becky, Susan, Tom]", nameValues)
println nameValues
}
@Test
public void convert_from_List_to_Array(){
List names = ["Mary", "Becky", "Susan", "Tom", "Mary"]
assertEquals(5, names.size())
String[] nameArray = names.toArray()
assertEquals(5, nameArray.size())
println nameArray
}
@Test
public void covert_from_evenNumber_list_to_map_with_toSpreadMap(){
def evenNumberList = ['key', 'value', 'name', 'mary', 'age', '40'] as Object[]
def map = evenNumberList.toSpreadMap()
assert 3 == map.size()
assert 'value' == map.key
assert 'mary' == map['name']
assert '40' == map['age']
}
}
3.5 Manipulation
Groovy Collection and Iterable interfaces define lots of methods to manipulate elements in a collection. In this step, we will demonstrate below common methods:
intersect(Collection)– create a collection composed of the intersection of both collectionsflatten{Closure}– return a new collection with flattened itemssplit{Closure}– splits all items into two collections based on the closuresort()– modifies all the elements in sorted ordertoSorted{Closure}– sorts all the elements and returns sorted listgroupby{Closure}– sorts all elements into groups by the mapping closurecountby{Closure}– sorts all elements into groups by the mapping closure and the counts of the group sizeremoveAll{Closure}-modifies the collection by removing the elements matching the closureaddAll(Object)– adds all the items from the given object to the collection
In this step, we will create a groovy unit test class Demo_Manipulate to show how to add, remove, sort, split, group, and flatten elements in a collection of List, Set, and Range.
Demo_Manipulate.groovy
package jcg.zheng.demo.groovy
import static org.junit.Assert.*
import org.junit.Test
class Demo_Manipulate {
@Test
public void when_sort_array_then_modify_array_to_sorted_order(){
String[] names = ["Mary", "Becky", "Susan", "Tom"]
println names
assertEquals(4, names.size())
assertEquals("Mary", names[0])
assertEquals("Becky", names[1])
assertEquals("Susan", names[2])
assertEquals("Tom", names[3])
names.sort()
assertEquals("Becky", names[0])
assertEquals("Mary", names[1])
assertEquals("Susan", names[2])
assertEquals("Tom", names[3])
println "Sorted name: "
println names
}
@Test
public void when_tosort_array_then_array_is_not_modified_but_new_sorted_array_is_returned(){
String[] names = ["Mary", "Becky", "Susan", "Tom"]
println names
assertEquals(4, names.size())
assertEquals("Mary", names[0])
assertEquals("Becky", names[1])
assertEquals("Susan", names[2])
assertEquals("Tom", names[3])
def sortedNames = names.toSorted()
assertEquals("Becky", sortedNames[0])
assertEquals("Mary", sortedNames[1])
assertEquals("Susan", sortedNames[2])
assertEquals("Tom", sortedNames[3])
println "Sorted name: "
println names
}
@Test
public void when_sort_list_then_the_list_is_modified_in_sorted_order(){
List names = ["Mary", "Becky", "Susan", "Tom"]
assertEquals(4, names.size())
assertEquals("Mary", names[0])
assertEquals("Becky", names[1])
assertEquals("Susan", names[2])
assertEquals("Tom", names[3])
names.sort()
assertEquals("Becky", names[0])
assertEquals("Mary", names[1])
assertEquals("Susan", names[2])
assertEquals("Tom", names[3])
println "Sorted name: "
names.each { print "${it}, "}
}
@Test
public void when_sort_persons_the_persons_not_modified_but_new_sorted_persons_is_returned(){
Person[] persons = [new Person("Mary", "Zheng"), new Person("Alex", "Zheng"), new Person("Allen", "Zheng")]
assertEquals("Mary", persons[0].firstName)
assertEquals("Alex", persons[1].firstName)
assertEquals("Allen", persons[2].firstName)
def orderByFirstName = persons.sort { it.firstName }
assertEquals("Alex", orderByFirstName[0].firstName)
assertEquals("Allen", orderByFirstName[1].firstName)
assertEquals("Mary", orderByFirstName[2].firstName)
orderByFirstName.each { println it }
}
@Test
public void when_sort_set_the_set_not_modified_but_new_sorted_set_is_returned(){
Set names = new HashSet()
names.add("Zhang")
names.add("Mary")
names.add("Zheng")
Set orderSet = names.sort()
orderSet.eachWithIndex { name, i -> println "${i} = '${name}'"}
}
@Test
public void when_groupby_list_with_matching_condition_it_returned_map_with_groupby_data(){
List names = ["Mary", "Becky", "Susan", "Tom"]
Map<Boolean, List> hasY = names.groupBy{it.contains("y")}
assertEquals(2, hasY.size())
assertTrue(hasY.keySet().contains(true))
assertTrue(hasY.keySet().contains(false))
assertEquals(2, hasY.get(true).size())
assertTrue(hasY.get(true).contains("Becky"))
assertTrue(hasY.get(true).contains("Mary"))
assertEquals(2, hasY.get(false).size())
assertTrue(hasY.get(false).contains("Susan"))
assertTrue(hasY.get(false).contains("Tom"))
println "\nGroup by name contains 'Y' or not: "
hasY.each { println "${it.key}-${it.value}" }
}
@Test
public void when_countby_list_with_matching_condition_it_returned_map_with_countby_count(){
List names = ["Mary", "Becky", "Susan", "Tom"]
Map hasY = names.countBy{it.contains("T")}
assertEquals(2, hasY.size())
assertTrue(hasY.keySet().contains(true))
assertTrue(hasY.keySet().contains(false))
assertEquals(1, hasY.get(true))
assertEquals(3, hasY.get(false))
println "\nCount by name contains 'T' or not: "
hasY.each { println "${it.key}-${it.value}" }
}
@Test
public void when_groupBy_it_returns_map_with_groupBy_data(){
def numbers = (1..50)
def sameUnitsDigits = numbers.groupBy{it%10}
sameUnitsDigits.each { println it}
}
@Test
public void when_split_set_it_returns_map_of_two_sets(){
Set mySet = [100, 200, 300, 400, 500, 600]
println mySet.split{it> 300}
}
@Test
public void when_flatten_set_it_becomes_one_big_flat_set(){
Set foodSet = [["apple", "banana"], "peas", "green beans", ["egg", "milk", ["cheess", "ice cream"]]]
assertEquals(4, foodSet.size())
Set flattenSet = foodSet.flatten()
assertEquals(8, flattenSet.size())
println flattenSet
}
@Test
public void when_intersect_set_it_finds_common_elements(){
Set firstSet = [1, 2, 3, 4, 5]
Set secondSet = [4, 5, 6, 7, 8]
Set intersectSet = firstSet.intersect(secondSet)
assertEquals(2, intersectSet.size())
def commonNumbers = [4, 5] as Set
assertTrue(commonNumbers.equals(intersectSet))
println intersectSet
}
@Test
public void when_removeAll_it_becomes_empty(){
Set initialSet = [1, 2, 3, 4, 5]
initialSet.removeAll([1, 2, 3, 4, 5])
assertTrue(initialSet.size() == 0)
}
@Test
public void demo_addAll_and_unique_list(){
List names = ["Mary", "Becky", "Susan", "Tom"]
names.addAll(["Mary", "Susan"])
assertEquals(6, names.size())
names.unique();
assertEquals(4, names.size())
println names
}
}
4. Demo
Execute all unit tests:


5. Groovy Collections – Summary
In this example, we demonstrated Groovy Collection libraries to find, sort, and manipulate items in a collection of list, map, set, and range.
6. Download the Source Code
This example consists of a Maven project which demonstrates the usage of Groovy Collection‘s find, sort, split, groupby, etc, methods to search, iterate, convert, and manipulate elements in a collection.
You can download the full source code of this example here: Sign up


