12 Complete Groovy Array Manipulation Examples for Beginners

Work through Groovy arrays with 12 practical examples. Create, access, sort, and convert arrays. Complete guide tested on Groovy 5.x.

“Arrays are the backbone of every programming language. Once you understand how Groovy handles them, you’ll realize how much Java boilerplate you’ve been writing for nothing.”

Donald Knuth, The Art of Computer Programming

Last Updated: March 2026 | Tested on: Groovy 5.x, Java 17+ | Difficulty: Beginner to Intermediate | Reading Time: 20 minutes

Arrays in Java are fixed-size, type-safe containers – and in Groovy they keep all that behavior while gaining extra methods, cleaner syntax, and smooth conversion between arrays and lists. This Groovy array manipulation guide covers creation, access, iteration, sorting, searching, and conversion with tested examples and real output.

This Groovy array manipulation guide walks you through what you need for working with arrays in Groovy. We’ll cover creation, access, iteration, sorting, searching, conversion, and the spread operator – all with tested examples and real output.

If you’re looking for list-specific operations like add(), remove(), and unique(), check out our Groovy List Tutorial. And once you finish this post, head over to Groovy Array Length and Size for more details on measuring array dimensions.

What Are Groovy Arrays?

At their core, Groovy arrays are the same Java arrays you already know. They are fixed-size, ordered collections stored in contiguous memory. What Groovy adds is syntactic sugar and extra GDK methods that make arrays far more pleasant to work with.

According to the official Groovy syntax documentation, Groovy does not have a native array literal syntax. Instead, you create arrays by coercing a list literal using the as keyword or by using Java-style array construction.

Key Points:

  • Groovy arrays are Java arrays under the hood – same memory layout, same performance
  • Arrays have a fixed size – once created, you cannot add or remove elements
  • You can create arrays using new Type[size], as Type[], or direct initialization
  • Groovy adds GDK methods like each(), collect(), find(), and sort() to arrays
  • The spread operator (*.) works on arrays just like it does on lists
  • Arrays and lists can be freely converted back and forth using toList() and toArray()

Array vs List in Groovy

Before we dig into arrays, let’s clear up something that confuses many Groovy beginners: the difference between arrays and lists. In Groovy, a literal like [1, 2, 3] creates a java.util.ArrayList, not an array. To get an actual array, you need to explicitly coerce it.

FeatureArrayList
TypeString[], int[]ArrayList, LinkedList
SizeFixed at creationDynamic – grows and shrinks
Syntax[1,2,3] as int[][1, 2, 3]
Add elementsNot possiblelist.add(item) or list << item
PerformanceSlightly faster for read accessMore flexible overall
Use caseFixed-size data, JNI, interopMost Groovy code

In day-to-day Groovy code, you’ll use lists far more often than arrays. But arrays are essential when you’re calling Java APIs that require them, working with primitive types for performance, or dealing with multidimensional data. For a full list tutorial, see our Groovy List Tutorial.

Creating Arrays

Groovy gives you several ways to create arrays. Here is each approach so you can pick the one that fits your situation.

Java-Style Construction

Java-Style Array Creation

// Create an empty array with a fixed size
String[] names = new String[5]
println names        // [null, null, null, null, null]
println names.length // 5

// Create an array with initial values
int[] numbers = [10, 20, 30, 40, 50]
println numbers      // [10, 20, 30, 40, 50]

Using the as Keyword

Array Creation with ‘as’

// Coerce a list literal into an array
def fruits = ['Apple', 'Banana', 'Cherry'] as String[]
println fruits.class.name  // [Ljava.lang.String;
println fruits             // [Apple, Banana, Cherry]

// Works with any type
def scores = [95, 87, 72, 100] as int[]
println scores.class.name  // [I
println scores             // [95, 87, 72, 100]

The as keyword is the most “Groovy” way to create arrays. It reads naturally and works with any type.

12 Practical Array Examples

Example 1: Accessing Array Elements

What we’re doing: Reading and writing individual elements by index, including negative indexing.

Example 1: Accessing Elements

def colors = ['Red', 'Green', 'Blue', 'Yellow', 'Purple'] as String[]

// Access by positive index (0-based)
println colors[0]    // First element
println colors[2]    // Third element

// Access by negative index (counts from the end)
println colors[-1]   // Last element
println colors[-2]   // Second to last

// Modify an element
colors[1] = 'Lime'
println colors

Output

Red
Blue
Purple
Yellow
[Red, Lime, Blue, Yellow, Purple]

What happened here: Groovy adds negative indexing to arrays, something Java doesn’t support. Index -1 always gives you the last element, -2 gives the second to last, and so on. You can also replace elements by assigning to an index – the array is mutable, just not resizable.

Example 2: Array Slicing with Ranges

What we’re doing: Extracting sub-arrays using Groovy’s range operator.

Example 2: Array Slicing

def nums = [10, 20, 30, 40, 50, 60, 70, 80] as int[]

// Slice with a range
println nums[2..5]     // Elements at index 2, 3, 4, 5

// Slice from beginning
println nums[0..3]     // First four elements

// Slice with negative range
println nums[-3..-1]   // Last three elements

// Reverse slice
println nums[4..1]     // Elements 4 down to 1

Output

[30, 40, 50, 60]
[10, 20, 30, 40]
[60, 70, 80]
[50, 40, 30, 20]

What happened here: Groovy’s range operator (..) lets you slice arrays elegantly. The result is a list, not an array, but you can coerce it back with as int[] if needed. Notice that a descending range like 4..1 reverses the order – a neat trick for reversing a portion of an array.

Example 3: Iterating Over Arrays

What we’re doing: Looping through arrays using different iteration styles.

Example 3: Iterating Arrays

def languages = ['Groovy', 'Java', 'Kotlin', 'Scala'] as String[]

// Using each() closure
print "each: "
languages.each { print "${it} " }
println()

// Using eachWithIndex()
languages.eachWithIndex { lang, i ->
    println "  [${i}] ${lang}"
}

// Using a for-in loop
print "for-in: "
for (lang in languages) {
    print "${lang} "
}
println()

// Using traditional for loop
print "for-loop: "
for (int i = 0; i < languages.length; i++) {
    print "${languages[i]} "
}
println()

Output

each: Groovy Java Kotlin Scala
  [0] Groovy
  [1] Java
  [2] Kotlin
  [3] Scala
for-in: Groovy Java Kotlin Scala
for-loop: Groovy Java Kotlin Scala

What happened here: Groovy gives you multiple ways to iterate arrays. The each() closure is the most idiomatic Groovy approach. eachWithIndex() is useful when you need the position alongside the value. The for-in loop is clean and readable, while the traditional for loop works identically to Java.

Example 4: Sorting Arrays

What we’re doing: Sorting arrays in ascending, descending, and custom order.

Example 4: Sorting Arrays

def numbers = [42, 8, 15, 23, 4, 16] as Integer[]

// Default sort (ascending)
def sorted = numbers.sort()
println "Ascending:  ${sorted}"

// Sort descending using a closure
def desc = numbers.sort { a, b -> b <=> a }
println "Descending: ${desc}"

// Sort strings by length
def words = ['Groovy', 'is', 'awesome', 'at', 'arrays'] as String[]
def byLength = words.sort { it.length() }
println "By length:  ${byLength}"

// Sort without modifying original (use false flag)
def original = [30, 10, 20] as Integer[]
def sortedCopy = original.sort(false)
println "Original:   ${original}"
println "Sorted:     ${sortedCopy}"

Output

Ascending:  [4, 8, 15, 16, 23, 42]
Descending: [42, 23, 16, 15, 8, 4]
By length:  [is, at, Groovy, arrays, awesome]
Original:   [30, 10, 20]
Sorted:     [10, 20, 30]

What happened here: Groovy’s sort() modifies the array in place and returns it. The spaceship operator (<=>) makes comparison closures clean and readable. Passing false to sort() returns a sorted copy without changing the original – very handy when you need both versions.

Example 5: Searching Arrays

What we’re doing: Finding elements in arrays using various search methods.

Example 5: Searching Arrays

def prices = [29.99, 49.99, 9.99, 79.99, 19.99] as Double[]

// Check if element exists
println "Contains 49.99? ${prices.contains(49.99)}"

// Find first match
def expensive = prices.find { it > 40 }
println "First > 40:  ${expensive}"

// Find all matches
def affordable = prices.findAll { it < 30 }
println "Under 30:    ${affordable}"

// Check if any element matches
println "Any > 100?   ${prices.any { it > 100 }}"
println "Any > 50?    ${prices.any { it > 50 }}"

// Check if all elements match
println "All > 5?     ${prices.every { it > 5 }}"
println "All > 20?    ${prices.every { it > 20 }}"

// Find index of element
def cities = ['Tokyo', 'London', 'Paris', 'Berlin'] as String[]
println "Paris index: ${cities.findIndexOf { it == 'Paris' }}"

Output

Contains 49.99? true
First > 40:  49.99
Under 30:    [29.99, 9.99, 19.99]
Any > 100?   false
Any > 50?    true
All > 5?     true
All > 20?    false
Paris index: 2

What happened here: All the powerful search methods you’d expect from Groovy lists also work on arrays. find() returns the first match, findAll() returns all matches as a list, any() checks if at least one element matches, and every() checks if all elements match. These come from the GDK – Groovy’s extensions to standard Java types.

Example 6: Converting Array to List and Back

What we’re doing: Converting between arrays and lists – one of the most common operations in Groovy.

Example 6: Array/List Conversion

// Array to List
def colorsArray = ['Red', 'Green', 'Blue'] as String[]
def colorsList = colorsArray.toList()
println "Array class: ${colorsArray.class.name}"
println "List class:  ${colorsList.class.name}"
println "List:        ${colorsList}"

// List to Array
def numList = [10, 20, 30, 40]
def numArray = numList as int[]
println "Array class: ${numArray.class.name}"
println "Array:       ${numArray}"

// Using Arrays.asList()
def fromAsList = Arrays.asList(colorsArray)
println "asList:      ${fromAsList}"

// Convert and add elements
def expanded = colorsArray.toList()
expanded << 'Yellow'
expanded << 'Purple'
println "Expanded:    ${expanded}"
def backToArray = expanded as String[]
println "Back:        ${backToArray}"

Output

Array class: [Ljava.lang.String;
List class:  java.util.ArrayList
List:        [Red, Green, Blue]
Array class: [I
Array:       [10, 20, 30, 40]
asList:      [Red, Green, Blue]
Expanded:    [Red, Green, Blue, Yellow, Purple]
Back:        [Red, Green, Blue, Yellow, Purple]

What happened here: The toList() method converts any array into a mutable ArrayList. Going the other way, as int[] or as String[] coerces a list back into an array. This pattern is extremely common – convert to a list when you need to add or remove elements, then convert back if a Java API requires an array.

Example 7: The Spread Operator on Arrays

What we’re doing: Using the spread operator (*.) to call methods on every element.

Example 7: Spread Operator

def names = ['alice', 'bob', 'charlie', 'diana'] as String[]

// Call toUpperCase() on every element
println names*.toUpperCase()

// Get length of each string
println names*.length()

// Chain: capitalize each name
println names*.capitalize()

// Spread with property access
class Person {
    String name
    int age
}

def people = [
    new Person(name: 'Alice', age: 30),
    new Person(name: 'Bob', age: 25),
    new Person(name: 'Charlie', age: 35)
] as Person[]

println "Names: ${people*.name}"
println "Ages:  ${people*.age}"
println "Sum:   ${people*.age.sum()}"

Output

[ALICE, BOB, CHARLIE, DIANA]
[5, 3, 7, 5]
[Alice, Bob, Charlie, Diana]
Names: [Alice, Bob, Charlie]
Ages:  [30, 25, 35]
Sum:   90

What happened here: The spread operator *. is one of Groovy’s most loved features. It calls a method or accesses a property on every element in the array and returns a list of results. Think of it as a shorthand for collect { it.methodName() }. You can chain it with other operations, making it incredibly expressive.

Example 8: Transforming Arrays with collect()

What we’re doing: Transforming each element in an array using the collect() method.

Example 8: collect() Transformation

def temps = [32, 68, 100, 212, 0] as int[]

// Convert Fahrenheit to Celsius
def celsius = temps.collect { ((it - 32) * 5 / 9).round(1) }
println "Celsius: ${celsius}"

// Double each value
def doubled = temps.collect { it * 2 }
println "Doubled: ${doubled}"

// Create formatted strings
def labels = temps.collect { "${it}°F" }
println "Labels:  ${labels}"

// Filter + transform in one step
def hotTemps = temps.findAll { it > 50 }.collect { "${it}°F is ${((it - 32) * 5 / 9).round(1)}°C" }
println "Hot temps:"
hotTemps.each { println "  ${it}" }

Output

Celsius: [0.0, 20.0, 37.8, 100.0, -17.8]
Doubled: [64, 136, 200, 424, 0]
Labels:  [32°F, 68°F, 100°F, 212°F, 0°F]
Hot temps:
  68°F is 20.0°C
  100°F is 37.8°C
  212°F is 100.0°C

What happened here: The collect() method transforms each element and returns a new list. It’s equivalent to map() in other languages. Chaining findAll() with collect() is a powerful pattern for filtering and transforming in one pipeline.

Example 9: Array Coercion with as

What we’re doing: Using the as keyword for type coercion between different array types.

Example 9: Array Coercion

// String numbers to int array
def stringNums = ['1', '2', '3', '4', '5']
def intArray = stringNums.collect { it.toInteger() } as int[]
println "int[]: ${intArray} (${intArray.class.name})"

// int array to double array
def ints = [10, 20, 30] as int[]
def doubles = ints.collect { it as double } as double[]
println "double[]: ${doubles} (${doubles.class.name})"

// List of mixed types to String array
def mixed = [42, 'hello', true, 3.14]
def strArray = mixed.collect { it.toString() } as String[]
println "String[]: ${strArray}"

// Coerce to Object array
def objArray = [1, 'two', 3.0, true] as Object[]
println "Object[]: ${objArray} (${objArray.class.name})"
println "Types: ${objArray.collect { it.class.simpleName }}"

Output

int[]: [1, 2, 3, 4, 5] ([I)
double[]: [10.0, 20.0, 30.0] ([D)
String[]: [42, hello, true, 3.14]
Object[]: [1, two, 3.0, true] ([Ljava.lang.Object;)
Types: [Integer, String, BigDecimal, Boolean]

What happened here: The as keyword is Groovy’s Swiss Army knife for type coercion. You can convert between any compatible types. When combined with collect(), you can transform and coerce in a single expression. The Object[] array is useful when you need to store mixed types in an array.

Example 10: Joining and Flattening Arrays

What we’re doing: Joining array elements into strings and flattening nested arrays.

Example 10: Join and Flatten

def tags = ['groovy', 'java', 'jvm', 'programming'] as String[]

// Join with separator
println tags.join(', ')
println tags.join(' | ')
println tags.join(' -> ')

// Join for CSV output
def row = ['Alice', '30', 'Engineer', 'New York'] as String[]
println row.join(',')

// Flatten nested arrays
def nested = [[1, 2], [3, 4], [5, 6]] as Object[]
def flat = nested.flatten()
println "Nested:    ${nested}"
println "Flattened: ${flat}"

// Flatten deeply nested structure
def deep = [1, [2, [3, [4, [5]]]]] as Object[]
println "Deep flat: ${deep.flatten()}"

Output

groovy, java, jvm, programming
groovy | java | jvm | programming
groovy -> java -> jvm -> programming
Alice,30,Engineer,New York
Nested:    [[1, 2], [3, 4], [5, 6]]
Flattened: [1, 2, 3, 4, 5, 6]
Deep flat: [1, 2, 3, 4, 5]

What happened here: The join() method concatenates all elements with a separator – perfect for building CSV rows, log messages, or display strings. The flatten() method recursively unwraps nested collections into a single flat list, no matter how deeply nested they are.

Example 11: Aggregate Operations on Arrays

What we’re doing: Computing sums, averages, min, max, and other aggregate values from arrays.

Example 11: Aggregate Operations

def scores = [85, 92, 78, 95, 88, 76, 91] as Integer[]

println "Sum:     ${scores.sum()}"
println "Min:     ${scores.min()}"
println "Max:     ${scores.max()}"
println "Count:   ${scores.length}"
println "Average: ${scores.sum() / scores.length}"

// Inject (reduce/fold)
def product = scores.inject(1) { acc, val -> acc * val }
println "Product: ${product}"

// Count elements matching condition
def highScores = scores.count { it >= 90 }
println "Scores >= 90: ${highScores}"

// Group by range
def grouped = scores.groupBy {
    it >= 90 ? 'A' : it >= 80 ? 'B' : 'C'
}
println "Grouped: ${grouped}"

Output

Sum:     605
Min:     76
Max:     95
Count:   7
Average: 86.4285714286
Product: 544422144
Scores >= 90: 3
Grouped: [B:[85, 88], A:[92, 95, 91], C:[78, 76]]

What happened here: Arrays in Groovy support the full suite of aggregate operations. inject() is Groovy’s version of reduce or fold – it accumulates a result by processing each element. The groupBy() method is incredibly useful for categorizing data. Want to learn more about array sizes? Check our Groovy Array Length and Size guide.

Example 12: Real-World Example – CSV Data Processing

What we’re doing: Processing CSV-like data using array manipulation techniques from this guide.

Example 12: Real-World CSV Processing

// Simulate CSV data as arrays
def headers = ['Name', 'Department', 'Salary'] as String[]
def rows = [
    ['Alice',   'Engineering', '95000'] as String[],
    ['Bob',     'Marketing',   '72000'] as String[],
    ['Charlie', 'Engineering', '88000'] as String[],
    ['Diana',   'Marketing',   '68000'] as String[],
    ['Eve',     'Engineering', '102000'] as String[]
]

// Print formatted header
println headers.collect { it.padRight(15) }.join('| ')
println '-' * 50

// Print formatted rows
rows.each { row ->
    println row.collect { it.padRight(15) }.join('| ')
}

// Calculate average salary by department
def salaryByDept = rows.groupBy { it[1] }
println "\nAverage Salaries:"
salaryByDept.each { dept, employees ->
    def avg = employees.collect { it[2].toInteger() }.sum() / employees.size()
    println "  ${dept}: \$${avg.round(0)}"
}

// Find highest paid employee
def highest = rows.max { it[2].toInteger() }
println "\nHighest paid: ${highest[0]} (\$${highest[2]})"

Output

Name           | Department     | Salary
--------------------------------------------------
Alice          | Engineering    | 95000
Bob            | Marketing      | 72000
Charlie        | Engineering    | 88000
Diana          | Marketing      | 68000
Eve            | Engineering    | 102000

Average Salaries:
  Engineering: $95000
  Marketing: $70000

Highest paid: Eve ($102000)

What happened here: This example pulls together multiple techniques – array access by index, collect() for transformation, groupBy() for categorization, join() for formatting, and max() for finding the highest value. This is the kind of data wrangling that Groovy arrays make concise and readable.

Multidimensional Arrays

Sometimes you need a grid – rows and columns of data. Groovy supports multidimensional arrays just like Java, but with cleaner syntax for creation and access.

Multidimensional Arrays

// Create a 3x3 matrix
int[][] matrix = [
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9]
]

// Access individual elements
println "Center: ${matrix[1][1]}"
println "Corner: ${matrix[0][0]}"
println "Last:   ${matrix[2][2]}"

// Print the matrix
println "\nMatrix:"
matrix.each { row ->
    println row.collect { String.format('%3d', it) }.join(' ')
}

// Transpose the matrix
def transposed = (0..2).collect { col ->
    (0..2).collect { row -> matrix[row][col] } as int[]
}
println "\nTransposed:"
transposed.each { row ->
    println row.collect { String.format('%3d', it) }.join(' ')
}

// Create an empty 2D array
String[][] grid = new String[3][4]
grid[0][0] = 'A1'
grid[1][2] = 'B3'
println "\nGrid[0][0]: ${grid[0][0]}"
println "Grid[1][2]: ${grid[1][2]}"
println "Grid[2][3]: ${grid[2][3]}"  // null - not yet assigned

Output

Center: 5
Corner: 1
Last:   9

Matrix:
  1   2   3
  4   5   6
  7   8   9

Transposed:
  1   4   7
  2   5   8
  3   6   9

Grid[0][0]: A1
Grid[1][2]: B3
Grid[2][3]: null

Multidimensional arrays are useful for matrices, game boards, grid-based data, and any situation where you need two-dimensional indexing. Groovy’s closure-based iteration makes working with them much more readable than nested Java for-loops.

Primitive vs Object Arrays

An important distinction in Groovy (inherited from Java) is the difference between primitive arrays and object arrays. Understanding this matters for performance and Java interop.

Primitive vs Object Arrays

// Primitive arrays
int[] primitiveInts = [1, 2, 3, 4, 5]
double[] primitiveDbl = [1.1, 2.2, 3.3]
boolean[] primitiveBool = [true, false, true]
char[] primitiveChar = ['a', 'b', 'c']

println "int[]:     ${primitiveInts.class.name}"     // [I
println "double[]:  ${primitiveDbl.class.name}"       // [D
println "boolean[]: ${primitiveBool.class.name}"      // [Z
println "char[]:    ${primitiveChar.class.name}"      // [C

// Object arrays (wrapper types)
Integer[] objectInts = [1, 2, 3, 4, 5]
Double[] objectDbl = [1.1, 2.2, 3.3]

println "Integer[]: ${objectInts.class.name}"         // [Ljava.lang.Integer;
println "Double[]:  ${objectDbl.class.name}"          // [Ljava.lang.Double;

// Key difference: primitive arrays cannot hold null
// int[] cannotHoldNull = [1, null, 3]  // ERROR!
Integer[] canHoldNull = [1, null, 3]
println "With null:  ${canHoldNull}"

// Default values differ
int[] defaultPrimitive = new int[3]
Integer[] defaultObject = new Integer[3]
println "int default:     ${defaultPrimitive}"    // [0, 0, 0]
println "Integer default: ${defaultObject}"       // [null, null, null]

Output

int[]:     [I
double[]:  [D
boolean[]: [Z
char[]:    [C
Integer[]: [Ljava.lang.Integer;
Double[]:  [Ljava.lang.Double;
With null:  [1, null, 3]
int default:     [0, 0, 0]
Integer default: [null, null, null]

Use primitive arrays (int[], double[]) when performance matters and you know you won’t need null values. Use object arrays (Integer[], Double[]) when you need nullable elements or want to use more GDK methods.

The Arrays Utility Class

Java’s java.util.Arrays class provides static methods for array operations. These work perfectly in Groovy and are useful for operations that GDK methods don’t cover.

Arrays Utility Class

import java.util.Arrays

def nums = [5, 3, 8, 1, 9, 2, 7] as int[]

// Sort using Arrays.sort()
int[] sorted = nums.clone()
Arrays.sort(sorted)
println "Sorted:      ${sorted}"

// Binary search (array must be sorted first)
int index = Arrays.binarySearch(sorted, 7)
println "Index of 7:  ${index}"

// Fill an array with a value
int[] filled = new int[5]
Arrays.fill(filled, 42)
println "Filled:      ${filled}"

// Copy a portion of an array
int[] partial = Arrays.copyOfRange(sorted, 2, 5)
println "Partial:     ${partial}"

// Compare two arrays
int[] a = [1, 2, 3] as int[]
int[] b = [1, 2, 3] as int[]
int[] c = [1, 2, 4] as int[]
println "a equals b?  ${Arrays.equals(a, b)}"
println "a equals c?  ${Arrays.equals(a, c)}"

// Convert to string for debugging
println "Debug:       ${Arrays.toString(nums)}"

// Deep comparison for multidimensional arrays
int[][] m1 = [[1, 2], [3, 4]]
int[][] m2 = [[1, 2], [3, 4]]
println "Deep equal?  ${Arrays.deepEquals(m1, m2)}"

Output

Sorted:      [1, 2, 3, 5, 7, 8, 9]
Index of 7:  4
Filled:      [42, 42, 42, 42, 42]
Partial:     [3, 5, 7]
a equals b?  true
a equals c?  false
Debug:       [5, 3, 8, 1, 9, 2, 7]
Deep equal?  true

While Groovy’s GDK methods handle most array operations, the Arrays utility class is still useful for binary search, filling arrays, deep equality checks, and range copies. According to the Groovy JDK documentation, GDK methods are added on top of existing Java functionality – so you get the best of both worlds.

Edge Cases and Best Practices

Empty Arrays

Empty Arrays

// Create empty arrays
String[] emptyStr = new String[0]
int[] emptyInt = [] as int[]
def emptyObj = [] as Object[]

println "Empty size: ${emptyStr.length}"        // 0
println "Is empty:   ${emptyStr.size() == 0}"   // true
println "toList:     ${emptyStr.toList()}"       // []

// Safe operations on empty arrays
println "Sum:  ${([] as Integer[]).sum()}"       // null - be careful!
println "Join: '${emptyStr.join(", ")}'"         // ''

Output

Empty size: 0
Is empty:   true
toList:     []
Sum:  null
Join: ''

Best Practices

DO:

  • Use lists ([]) by default – switch to arrays only when needed
  • Use as Type[] for clear, readable array creation
  • Prefer GDK methods (each, collect, find) over manual loops
  • Convert to a list when you need to add or remove elements, then convert back
  • Use sort(false) when you want a sorted copy without modifying the original

DON’T:

  • Try to add elements to an array – use a list instead
  • Confuse list literals ([1,2,3]) with arrays – the literal creates an ArrayList
  • Use arrays for dynamic collections – arrays are fixed size
  • Forget that sort() mutates the array in place by default

Common Pitfalls

Pitfall 1: List Literal Is Not an Array

Problem: Assuming [1, 2, 3] creates an array.

Pitfall 1: List vs Array

// This creates an ArrayList, NOT an array
def notAnArray = [1, 2, 3]
println notAnArray.class.name  // java.util.ArrayList

// This creates an actual array
def realArray = [1, 2, 3] as int[]
println realArray.class.name   // [I

Solution: Always use as Type[] or explicit type declaration when you need an array.

Pitfall 2: ArrayIndexOutOfBoundsException

Problem: Accessing an index beyond the array’s bounds.

Pitfall 2: Index Out of Bounds

def arr = [10, 20, 30] as int[]

// This throws ArrayIndexOutOfBoundsException
try {
    println arr[5]
} catch (ArrayIndexOutOfBoundsException e) {
    println "Error: ${e.message}"
}

// Safe approach - check length first
def index = 5
if (index >= 0 && index < arr.length) {
    println arr[index]
} else {
    println "Index ${index} is out of bounds (size: ${arr.length})"
}

Output

Error: Index 5 out of bounds for length 3
Index 5 is out of bounds (size: 3)

Pitfall 3: Mutating Sort Surprise

Problem: Not realizing sort() modifies the original array.

Pitfall 3: Mutating Sort

def original = [30, 10, 20] as Integer[]
def sorted = original.sort()

// Both point to the same mutated array!
println "Original: ${original}"  // [10, 20, 30] - modified!
println "Sorted:   ${sorted}"    // [10, 20, 30]

// Fix: use sort(false) for a non-mutating sort
def original2 = [30, 10, 20] as Integer[]
def sorted2 = original2.sort(false)
println "Original2: ${original2}"  // [30, 10, 20] - preserved
println "Sorted2:   ${sorted2}"    // [10, 20, 30]

Output

Original: [10, 20, 30]
Sorted:   [10, 20, 30]
Original2: [30, 10, 20]
Sorted2:   [10, 20, 30]

Solution: Always use sort(false) if you need to preserve the original order. This returns a sorted copy without touching the original.

Conclusion

Groovy array manipulation combines the raw performance of Java arrays with the expressiveness of Groovy’s GDK methods. Slicing with ranges, transforming with collect(), searching with find(), or spreading with *. – arrays in Groovy are far more pleasant to work with than in plain Java.

That said, remember the golden rule: use lists by default, and switch to arrays only when you have a specific reason – Java API requirements, performance with primitives, or fixed-size data. The smooth toList() and as Type[] conversions mean you can switch between them whenever needed.

For more on array dimensions and size checking, head over to our Groovy Array Length and Size guide. And if you haven’t already, check out our Groovy List Tutorial for the full picture on Groovy collections.

Summary

  • Groovy arrays are Java arrays with extra GDK methods – same performance, better syntax
  • Use as Type[] to create arrays from list literals
  • Negative indexing (array[-1]) and range slicing (array[2..5]) work on arrays
  • The spread operator (*.) calls a method on every element
  • Convert freely between arrays and lists with toList() and as Type[]
  • Use sort(false) to get a sorted copy without mutating the original

If you also work with build tools, CI/CD pipelines, or cloud CLIs, check out Command Playground to practice 105+ CLI tools directly in your browser — no install needed.

Up next: Groovy Array Length and Size

Frequently Asked Questions

How do you create an array in Groovy?

You can create arrays in Groovy using Java-style construction (new String[5]) or by coercing a list literal with the as keyword (['a', 'b', 'c'] as String[]). You can also declare typed arrays like int[] nums = [1, 2, 3]. The as Type[] approach is the most idiomatic Groovy style.

What is the difference between an array and a list in Groovy?

Arrays have a fixed size and are backed by Java arrays (int[], String[]), while lists are dynamic and backed by ArrayList. A literal like [1, 2, 3] creates a list in Groovy, not an array. Use as int[] to get an actual array. Lists support add() and remove() while arrays do not.

How do you convert an array to a list in Groovy?

Call toList() on any array to get a mutable ArrayList: def list = myArray.toList(). You can also use Arrays.asList(myArray). To convert back, use myList as String[] or myList.toArray(). Groovy makes these conversions smooth.

Does the spread operator work on Groovy arrays?

Yes, the spread operator (*.) works on arrays exactly like it does on lists. For example, names*.toUpperCase() calls toUpperCase() on every element and returns a list of results. You can also access properties: people*.name extracts the name from each element.

How do you sort an array in Groovy without modifying the original?

Use sort(false) to return a sorted copy without changing the original array: def sorted = myArray.sort(false). By default, sort() modifies the array in place. You can also pass a closure for custom sorting: myArray.sort(false) { a, b -> b <=> a } for descending order.

Previous in Series: Groovy List Contains, Remove, and Deduplicate

Next in Series: Groovy Array Length and Size

Related Topics You Might Like:

This post is part of the Groovy & Grails Cookbook series on TechnoScripts.com

RahulAuthor posts

Avatar for Rahul

Rahul is a passionate IT professional who loves to sharing his knowledge with others and inspiring them to expand their technical knowledge. Rahul's current objective is to write informative and easy-to-understand articles to help people avoid day-to-day technical issues altogether. Follow Rahul's blog to stay informed on the latest trends in IT and gain insights into how to tackle complex technical issues. Whether you're a beginner or an expert in the field, Rahul's articles are sure to leave you feeling inspired and informed.

No comment

Leave a Reply

Your email address will not be published. Required fields are marked *