Skip to content
Collections Deep
step 1/4

Reading — step 1 of 4

Learn

~2 min readSpread, Collections Deep, HTTP

Beyond each, collect, find, Groovy collections have a rich operator set.

Grouping

def people = [
    [name: "Ada", country: "UK"],
    [name: "Bob", country: "US"],
    [name: "Carol", country: "UK"],
]

filters = people.groupBy { it.country }
// [UK: [Ada, Carol], US: [Bob]]

people.countBy { it.country }
// [UK: 2, US: 1]

Stats

def nums = [3, 1, 4, 1, 5, 9, 2, 6]
nums.sum()             // 31
nums.min()             // 1
nums.max()             // 9
nums.size()             // 8
nums.average()          // 3.875 (returns BigDecimal)
nums.unique()           // [3, 1, 4, 5, 9, 2, 6]
nums.unique(false)       // copy, not mutate
nums.sort()             // mutates AND returns

Inject (reduce)

nums.inject(0) { acc, n -> acc + n }          // 31 (sum)
nums.inject(1) { acc, n -> acc * n }          // product
nums.inject([]) { acc, n -> acc + (n * 2) }   // alt to collect

Chunking

[1, 2, 3, 4, 5, 6, 7, 8].collate(3)
// [[1,2,3], [4,5,6], [7,8]]

[1, 2, 3, 4, 5].collate(3, 1)
// [[1,2,3], [2,3,4], [3,4,5]]

Zip

[1, 2, 3].transpose([10, 20, 30])
// [[1, 10], [2, 20], [3, 30]]

// Or use collect with index:
["a", "b", "c"].withIndex().collect { item, i -> "$i: $item" }
// ["0: a", "1: b", "2: c"]

Take and drop

[1, 2, 3, 4, 5].take(3)        // [1, 2, 3]
[1, 2, 3, 4, 5].drop(3)        // [4, 5]
[1, 2, 3, 4, 5].takeWhile { it < 3 }      // [1, 2]
[1, 2, 3, 4, 5].dropWhile { it < 3 }      // [3, 4, 5]

Tap

Let you return-while-side-effect:

def result = computeThing().tap { println it }
// prints, then returns result

Functional composition

Groovy supports chaining method calls:

nums
    .findAll { it > 1 }
    .collect { it * 2 }
    .sum()

This is Groovy at its best — readable streaming pipelines.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…