Step 1 of 4 · Reading · ~2 min
Learn
Spread, Collections Deep, HTTP
Groovy's spread operators turn collection methods into one-liners.
Spread-dot *.
def users = [[name: "Ada"], [name: "Bob"], [name: "Carol"]]
def names = users*.name // ["Ada", "Bob", "Carol"]
Equivalent to users.collect { it.name } — *. is the shortcut. The operator is spelled *., written directly after the collection.
Spread argument *
Pass a list as multiple arguments:
def bounds = [10, 20]
Math.max(*bounds) // 20 — exactly Math.max(10, 20)
def list = [10, 20, 30, 40]
Math.max(list[0], list[1]) // verbose
Math.max(*list[0..1]) // spread + slice, same result
// The arity still has to match. Math.max has no three-argument form, so
// Math.max(*[1, 2, 3]) fails at runtime with a MissingMethodException.
Useful for variadic functions:
def formatNames = { String pattern, Object... names ->
names.collect { String.format(pattern, it) }
}
def arr = ["Ada", "Bob"]
println formatNames("Hello, %s!", *arr)
// [Hello, Ada!, Hello, Bob!]
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 spread-dot 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() }.
Up nextCollections DeepSpread, Collections Deep, HTTP
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…