Groovy Collection Methods
last modified October 15, 2026
Groovy adds many closure-based methods to Java collections. They let you
summarize, group, and split data in a few lines. This tutorial covers
inject, groupBy, countBy,
collate, eachWithIndex, and related methods, with
examples for lists and maps.
Reducing a List with inject
inject combines the elements of a collection into one value. It
takes an initial value and a closure that receives the accumulated result and
the next element.
def prices = [12.5, 3.25, 8.0]
def total = prices.inject(0) { sum, price -> sum + price }
println total
def longest = ["go", "groovy", "java"].inject("") { best, word ->
word.size() > best.size() ? word : best
}
println longest
The first call adds the prices starting from 0. The second call
keeps the longest word seen so far. The initial value sets the type of the
result, so use "" for strings and 0 for numbers.
Grouping with groupBy
groupBy returns a map whose keys come from the closure and whose
values are lists of matching elements.
def words = ["apple", "avocado", "banana", "blueberry", "cherry"]
def byLetter = words.groupBy { it[0] }
println byLetter
println byLetter.a
Each word is placed under its first letter. The map keys are
a, b, and c, and each value is a list.
This is a direct way to build an index from a list of records.
Counting with countBy
countBy groups the elements and counts how many fall into each
group. It is a shorthand for groupBy followed by counting each
list.
def votes = ["red", "blue", "red", "green", "red", "blue"]
def counts = votes.countBy { it }
println counts
def best = counts.max { it.value }
println "Winner: ${best.key} with ${best.value} votes"
countBy { it } counts each distinct value. The
max method on a map takes a closure that picks the comparison
value, so the entry with the highest count is returned.
Splitting with collate
collate divides a list into sublists of a given size. It is useful
for batching work, such as sending records in groups or building pages.
def ids = (1..7).toList()
ids.collate(3).each { batch ->
println "Batch: $batch"
}
println ids.collate(3, false)
The default form keeps the last, shorter batch, [7]. Passing
false as the second argument drops an incomplete final batch, so the
second println prints only the two full batches.
Indexed Iteration with eachWithIndex
eachWithIndex passes the element and its position to the closure.
Use withIndex when you need the index as a list of pairs.
def steps = ["Plan", "Build", "Test"]
steps.eachWithIndex { step, i ->
println "${i + 1}. $step"
}
println steps.withIndex().collect { step, i -> "$i:$step" }
Indexes start at zero, so the example adds one for display. The
withIndex call returns pairs that can be transformed with
collect.
Other Useful Methods
sum, max, and min accept a closure to
choose the value to compare. unique removes duplicates from a list
in place.
def orders = [[item: "pen", qty: 3], [item: "book", qty: 1], [item: "pen", qty: 2]]
println orders.sum { it.qty }
println orders.max { it.qty }.item
def items = orders*.item
println items.unique(false)
sum adds the quantities, and max returns the order with
the largest quantity. unique(false) removes duplicates without
changing the original list.
Best Practices
- Pick the right method: Use
groupByfor lists of values per key andcountBywhen only counts matter. - Give inject a typed start: The initial value determines the type of the result.
- Keep closures short: If a closure grows beyond a few lines, extract a named method.
- Mind side effects: Prefer returning values from closures over changing outside variables.
Source
Groovy Development Kit | Groovy GDK API
Groovy's collection methods turn common loops into single expressions. Learn
inject, groupBy, and countBy first, since
they cover most grouping and summary tasks.
Author
List all Groovy tutorials.