Skip to content
Spread Operator
step 1/4

Reading — step 1 of 4

Learn

~1 min readSpread, Collections Deep, HTTP

Groovy's spread operators turn collection methods into one-liners.

Spread method .*

def users = [[name: "Ada"], [name: "Bob"], [name: "Carol"]]
def names = users*.name              // ["Ada", "Bob", "Carol"]

Equivalent to users.collect { it.name }. The .*. is a shortcut.

Spread argument *

Pass a list as multiple arguments:

def args = [1, 2, 3]
Math.max(*args)             // calls Math.max(1, 2, 3) — but Math.max takes 2 args

def list = [10, 20, 30, 40]
Math.max(list[0], list[1])   // verbose
Math.max(*list[0..1])        // spread + slice

Useful for variadic functions:

def formatNames = { String pattern, ... names ->
    names.collect { String.format(pattern, it) }
}

def arr = ["Ada", "Bob"]
formatNames("Hello, %s!", *arr)

Spread map

def defaults = [color: "blue", size: 10]
def custom = [size: 20]
def merged = [*:defaults, *:custom]    // [color:blue, size:20]

Right-side wins on conflicts.

Spread in collection literals

def a = [1, 2, 3]
def b = [4, 5, 6]
def combined = [*a, *b]              // [1, 2, 3, 4, 5, 6]
def wrapped = [0, *a, *b, 100]       // [0, 1, 2, 3, 4, 5, 6, 100]

Useful patterns

Extract a field from a list of records:

def users = [...]
def ids = users*.id
ids.unique()                          // distinct ids

Cascade with .*. for chained access:

def users = [[address: [city: "London"]], [address: [city: "Paris"]]]
def cities = users*.address*.city     // ["London", "Paris"]

Method invocation:

def strings = ["foo", "bar", "baz"]
def caps = strings*.toUpperCase()      // ["FOO", "BAR", "BAZ"]

This is shorthand for strings.collect { it.toUpperCase() }.

Discussion

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

Sign in to post a comment or reply.

Loading…