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.
Table of Contents
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(), andsort()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()andtoArray()
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.
| Feature | Array | List |
|---|---|---|
| Type | String[], int[] | ArrayList, LinkedList |
| Size | Fixed at creation | Dynamic – grows and shrinks |
| Syntax | [1,2,3] as int[] | [1, 2, 3] |
| Add elements | Not possible | list.add(item) or list << item |
| Performance | Slightly faster for read access | More flexible overall |
| Use case | Fixed-size data, JNI, interop | Most 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()andas 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.
Related Posts
Previous in Series: Groovy List Contains, Remove, and Deduplicate
Next in Series: Groovy Array Length and Size
Related Topics You Might Like:
- Groovy List Tutorial with Examples
- Groovy List Contains, Remove, and Deduplicate
- Groovy Closures – The Complete Guide
This post is part of the Groovy & Grails Cookbook series on TechnoScripts.com

No comment