Get Groovy array length using length, size(), and count(). 10 tested examples covering arrays, lists, maps, and strings on Groovy 5.x.
“Knowing how many elements you have is the first step to doing something useful with them.”
Edsger Dijkstra, A Discipline of Programming
Last Updated: March 2026 | Tested on: Groovy 5.x, Java 17+ | Difficulty: Beginner | Reading Time: 14 minutes
Checking how many elements an array or collection contains is one of the most frequent operations in any Groovy program. Input validation, data iteration, dynamic structures – all of these require a reliable way to get the groovy array length, and Groovy gives you multiple options depending on the type.
Here is the thing that trips up many developers coming from Java: Groovy gives you multiple ways to get the size of a collection, and each one works slightly differently depending on the type you are working with. Java arrays use the .length property. Java Strings use .length(). Java Collections use .size(). Groovy simplifies all of this, but you still need to know which approach to use and when.
In this tutorial, we will walk through 10 practical examples that cover every scenario: .length on arrays, .size() on lists and maps, .length() on strings, count() with closures, multidimensional arrays, null safety, and more. If you have been following along with our Groovy array manipulation guide, this picks up right where we left off. And if you need a refresher on lists, check out the Groovy list tutorial.
Table of Contents
Understanding Length, Size, and Count in Groovy
Before jumping into examples, let us clarify the three main ways Groovy lets you determine how many elements something contains. Each one has a specific use case, and understanding the differences will save you from unexpected errors.
The .length Property
The .length property is a Java-native feature that works on arrays. It is not a method call – it is a field access. This means no parentheses. When you create a Java-style array with new int[5] or use the as keyword to coerce a list into an array, .length gives you the fixed size of that array.
The .size() Method
The .size() method is the GDK (Groovy Development Kit) universal approach. It works on arrays, lists, maps, sets, strings, and even ranges. According to the Groovy GDK documentation for arrays, Groovy adds a size() method to arrays that delegates to .length. This means you can use .size() everywhere and never worry about whether you have an array or a list.
The .count() Method
The .count() method is different from the other two. It does not return the total number of elements. Instead, it counts elements that match a specific value or satisfy a closure condition. Think of it as a filtered count – it answers “how many of these elements meet my criteria?”
Now that you know the theory, let us see all three in action with real, tested examples.
Quick Reference Table
| Type | .length | .size() | .length() | .count() |
|---|---|---|---|---|
Java Array (int[], String[]) | Yes (property) | Yes (GDK) | No | Yes (GDK) |
List (ArrayList) | No | Yes (native) | No | Yes (GDK) |
Map (HashMap) | No | Yes (native) | No | Yes (GDK) |
Set (HashSet) | No | Yes (native) | No | Yes (GDK) |
| String | No | Yes (GDK) | Yes (native) | Yes (GDK) |
Range (1..10) | No | Yes (native) | No | Yes (GDK) |
The takeaway: .size() works on everything. If you want one method to remember, that is the one.
10 Practical Examples
Example 1: .length Property on Arrays
What we’re doing: Using the Java-native .length property to get the size of different array types.
Example 1: .length on Arrays
// Integer array
int[] numbers = [10, 20, 30, 40, 50]
println "int[] length: ${numbers.length}"
// String array
String[] fruits = ['Apple', 'Banana', 'Cherry']
println "String[] length: ${fruits.length}"
// Array created with 'as' keyword
def colors = ['Red', 'Green', 'Blue'] as String[]
println "colors[] length: ${colors.length}"
// Empty array
def empty = new int[0]
println "Empty array length: ${empty.length}"
// Pre-allocated array with fixed size
def preallocated = new String[10]
println "Pre-allocated length: ${preallocated.length}"
Output
int[] length: 5 String[] length: 3 colors[] length: 3 Empty array length: 0 Pre-allocated length: 10
What happened here: The .length property returns the fixed capacity of a Java array. Notice that the pre-allocated array reports 10 even though all its elements are null. That is because .length reflects the array’s declared size, not how many non-null elements it contains. This is a key distinction if you are coming from dynamic languages where “length” means “number of actual values.”
Example 2: .size() Method (GDK Universal Approach)
What we’re doing: Using the GDK .size() method on arrays, lists, and other collection types.
Example 2: .size() on Everything
// Array
String[] langs = ['Groovy', 'Java', 'Kotlin']
println "Array size(): ${langs.size()}"
// List (ArrayList)
def cities = ['London', 'Paris', 'Tokyo', 'Sydney']
println "List size(): ${cities.size()}"
// Map
def scores = [Alice: 95, Bob: 87, Charlie: 92]
println "Map size(): ${scores.size()}"
// Set
def uniqueNums = [1, 2, 3, 2, 1] as Set
println "Set size(): ${uniqueNums.size()}"
// Range
def range = 1..100
println "Range size(): ${range.size()}"
// String
def greeting = "Hello, Groovy!"
println "String size(): ${greeting.size()}"
Output
Array size(): 3 List size(): 4 Map size(): 3 Set size(): 3 Range size(): 100 String size(): 14
What happened here: The .size() method is the Swiss Army knife of Groovy collection sizing. It works on every type – arrays, lists, maps, sets, ranges, and strings. For arrays, Groovy’s GDK adds size() as a convenience that wraps .length. For lists and maps, it calls the native Java Collection.size(). For strings, it delegates to .length(). One method, everywhere. That is Groovy’s philosophy.
Example 3: .length() on Strings
What we’re doing: Using .length() on strings, plus comparing it with .size().
Example 3: .length() on Strings
def text = "Groovy Programming"
// Java's native String.length()
println "length(): ${text.length()}"
// Groovy's GDK size() - same result
println "size(): ${text.size()}"
// Empty string
println "Empty length(): ${''.length()}"
println "Empty size(): ${''.size()}"
// Unicode characters
def emoji = "Hello \u2764"
println "Unicode length(): ${emoji.length()}"
// GString length
def name = "World"
def gstr = "Hello, ${name}!"
println "GString length(): ${gstr.length()}"
println "GString size(): ${gstr.size()}"
Output
length(): 18 size(): 18 Empty length(): 0 Empty size(): 0 Unicode length(): 7 GString length(): 13 GString size(): 13
What happened here: For strings, .length() and .size() return the exact same value – the number of characters. The .length() method is Java’s native approach, while .size() is added by the GDK. Both work on GStrings too. The .length() method on strings uses parentheses because it is a method – do not confuse it with the .length property on arrays (no parentheses).
Example 4: size() on Lists and Maps
What we’re doing: Using .size() on Groovy’s primary collection types – lists and maps. For a deeper look at lists, see our Groovy list tutorial.
Example 4: Lists and Maps
// List - size reflects actual elements
def animals = ['Dog', 'Cat', 'Bird', 'Fish']
println "Animals: ${animals.size()} items"
// Dynamic list - size changes as you add/remove
def tasks = []
tasks << 'Write code'
tasks << 'Test code'
tasks << 'Deploy'
println "Tasks after adding: ${tasks.size()}"
tasks.remove('Test code')
println "Tasks after removing: ${tasks.size()}"
// Nested map
def config = [
database: [host: 'localhost', port: 5432],
cache : [host: 'redis', port: 6379, ttl: 300]
]
println "Config entries: ${config.size()}"
println "DB settings: ${config.database.size()}"
println "Cache settings: ${config.cache.size()}"
// Map of lists
def classroom = [
math : ['Alice', 'Bob', 'Charlie'],
science: ['Dave', 'Eve'],
english: ['Frank', 'Grace', 'Heidi', 'Ivan']
]
classroom.each { subject, students ->
println "${subject}: ${students.size()} students"
}
Output
Animals: 4 items Tasks after adding: 3 Tasks after removing: 2 Config entries: 2 DB settings: 2 Cache settings: 3 math: 3 students science: 2 students english: 4 students
What happened here: Unlike arrays, lists are dynamic – their .size() changes as you add or remove elements. Maps report the number of key-value pairs. Nested maps and lists each track their own size independently, so you can query at any level. This is especially useful in configuration parsing and data processing pipelines.
Example 5: count() with Closures
What we’re doing: Using .count() to count elements matching specific conditions.
Example 5: count() with Closures
def numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// Count even numbers
println "Even numbers: ${numbers.count { it % 2 == 0 }}"
// Count numbers greater than 5
println "Greater than 5: ${numbers.count { it > 5 }}"
// Count specific value
println "Count of 3: ${numbers.count(3)}"
// Count with strings
def words = ['groovy', 'java', 'groovy', 'kotlin', 'groovy', 'scala']
println "Occurrences of 'groovy': ${words.count('groovy')}"
// Count with closure on strings
def names = ['Alice', 'Bob', 'Amanda', 'Charlie', 'Anna']
println "Names starting with 'A': ${names.count { it.startsWith('A') }}"
// Count on a string (characters)
def sentence = "Hello World"
println "Lowercase 'l' count: ${sentence.count('l')}"
println "Vowels: ${sentence.toLowerCase().toList().count { it in ['a','e','i','o','u'] }}"
Output
Even numbers: 5 Greater than 5: 5 Count of 3: 1 Occurrences of 'groovy': 3 Names starting with 'A': 3 Lowercase 'l' count: 3 Vowels: 3
What happened here: The .count() method is incredibly versatile. Pass it a value and it counts exact matches. Pass it a closure and it counts every element where the closure returns true. This is far cleaner than writing a loop with a counter variable. It works on arrays, lists, and strings. The count() method on strings counts substring occurrences, not characters – so "Hello".count("ll") returns 1.
Example 6: isEmpty() – Check for Empty Collections
What we’re doing: Using .isEmpty() as a companion to .size() for cleaner empty checks.
Example 6: isEmpty()
def fullList = [1, 2, 3]
def emptyList = []
def emptyMap = [:]
def emptyString = ""
def emptyArray = new int[0]
// isEmpty() on different types
println "Full list isEmpty: ${fullList.isEmpty()}"
println "Empty list isEmpty: ${emptyList.isEmpty()}"
println "Empty map isEmpty: ${emptyMap.isEmpty()}"
println "Empty string isEmpty: ${emptyString.isEmpty()}"
// Groovy truth - empty collections are falsy
if (fullList) {
println "fullList is truthy (size: ${fullList.size()})"
}
if (!emptyList) {
println "emptyList is falsy"
}
// Practical usage - guard clause
def processItems(items) {
if (!items || items.isEmpty()) {
println "No items to process"
return
}
println "Processing ${items.size()} items..."
}
processItems([10, 20, 30])
processItems([])
processItems(null)
Output
Full list isEmpty: false Empty list isEmpty: true Empty map isEmpty: true Empty string isEmpty: true fullList is truthy (size: 3) emptyList is falsy Processing 3 items... No items to process No items to process
What happened here: While .size() == 0 works, .isEmpty() is more readable and expressive. Even better, Groovy’s truth system treats empty collections as false, so you can just write if (myList) to check for non-empty. The ?. operator handles null safely – more on that in Example 10.
Example 7: Counting with Conditions
What we’re doing: Combining .size(), .count(), .findAll(), and .grep() for advanced conditional counting.
Example 7: Conditional Counting
def employees = [
[name: 'Alice', dept: 'Engineering', salary: 95000],
[name: 'Bob', dept: 'Marketing', salary: 72000],
[name: 'Charlie', dept: 'Engineering', salary: 88000],
[name: 'Diana', dept: 'Sales', salary: 68000],
[name: 'Eve', dept: 'Engineering', salary: 102000],
[name: 'Frank', dept: 'Marketing', salary: 78000]
]
// Total employees
println "Total employees: ${employees.size()}"
// Count by department using count()
println "Engineers: ${employees.count { it.dept == 'Engineering' }}"
// Count using findAll().size()
def highEarners = employees.findAll { it.salary > 80000 }
println "Earning > 80K: ${highEarners.size()}"
// Group and count
def byDept = employees.groupBy { it.dept }
byDept.each { dept, members ->
println "${dept}: ${members.size()} employees"
}
// Count with grep (pattern matching)
def mixedData = [1, 'hello', 2.5, 'world', 3, null, true]
println "Integers: ${mixedData.grep(Integer).size()}"
println "Strings: ${mixedData.grep(String).size()}"
println "Non-null: ${mixedData.grep().size()}"
Output
Total employees: 6 Engineers: 3 Earning > 80K: 3 Engineering: 3 employees Marketing: 2 employees Sales: 1 employees Integers: 2 Strings: 2 Non-null: 6
What happened here: Groovy offers multiple ways to count with conditions. Use .count{} when you just need the number. Use .findAll{}.size() when you also need the matching elements. Use .groupBy{} when you need counts per category. And .grep() filters by type or pattern – calling it with no arguments removes null values.
Example 8: Length of Multidimensional Arrays
What we’re doing: Getting the size of multidimensional (nested) arrays and jagged arrays.
Example 8: Multidimensional Arrays
// 2D array (matrix)
int[][] matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
println "Rows: ${matrix.length}"
println "Columns in row 0: ${matrix[0].length}"
println "Total elements: ${matrix.length * matrix[0].length}"
// Jagged array (rows of different lengths)
String[][] jagged = [
['A', 'B'],
['C', 'D', 'E', 'F'],
['G']
]
println "\nJagged array rows: ${jagged.length}"
jagged.eachWithIndex { row, i ->
println "Row ${i}: ${row.length} elements -> ${row}"
}
// Total elements in a jagged array
def totalElements = jagged.collect { it.length }.sum()
println "Total elements in jagged: ${totalElements}"
// 2D list (list of lists)
def grid = [
[1, 2, 3],
[4, 5, 6]
]
println "\nGrid rows: ${grid.size()}"
println "Grid cols: ${grid[0].size()}"
println "Flat size: ${grid.flatten().size()}"
Output
Rows: 3 Columns in row 0: 3 Total elements: 9 Jagged array rows: 3 Row 0: 2 elements -> [A, B] Row 1: 4 elements -> [C, D, E, F] Row 2: 1 elements -> [G] Total elements in jagged: 7 Grid rows: 2 Grid cols: 3 Flat size: 6
What happened here: For a 2D array, .length on the outer array gives rows, and .length on each inner array gives columns. With jagged arrays, each row can have a different length, so you need to check each one individually. For lists of lists, .flatten().size() is a quick way to count all nested elements. This comes up often when processing CSV data or building game boards.
Example 9: Difference Between length and size()
What we’re doing: Demonstrating exactly when .length and .size() behave differently.
Example 9: length vs size()
// On arrays - both work, same result
int[] arr = [10, 20, 30]
println "Array .length: ${arr.length}"
println "Array .size(): ${arr.size()}"
println "Same result: ${arr.length == arr.size()}"
// On strings - length() is a method, not a property
def str = "Groovy"
println "\nString .length(): ${str.length()}"
println "String .size(): ${str.size()}"
// On lists - only size() works
def list = [1, 2, 3, 4, 5]
println "\nList .size(): ${list.size()}"
// list.length would throw MissingPropertyException
// Key difference: arrays are fixed, lists are dynamic
int[] fixedArr = new int[5] // pre-allocated with zeros
fixedArr[0] = 100
fixedArr[1] = 200
println "\nFixed array length: ${fixedArr.length}" // 5, not 2
println "Fixed array content: ${fixedArr}"
def dynamicList = []
dynamicList << 100
dynamicList << 200
println "Dynamic list size: ${dynamicList.size()}" // 2
println "Dynamic list content: ${dynamicList}"
// Using size() uniformly - works everywhere
def checkSize(obj) {
try {
println "${obj.getClass().simpleName} -> size(): ${obj.size()}"
} catch (e) {
println "Error: ${e.message}"
}
}
checkSize([1, 2, 3] as int[])
checkSize([1, 2, 3])
checkSize([a: 1, b: 2])
checkSize("hello")
checkSize(1..10)
Output
Array .length: 3 Array .size(): 3 Same result: true String .length(): 6 String .size(): 6 List .size(): 5 Fixed array length: 5 Fixed array content: [100, 200, 0, 0, 0] Dynamic list size: 2 Dynamic list content: [100, 200] int[] -> size(): 3 ArrayList -> size(): 3 LinkedHashMap -> size(): 2 String -> size(): 5 IntRange -> size(): 10
What happened here: This is the key difference. Array .length returns the allocated capacity, regardless of how many elements you actually set. List .size() returns the actual number of elements. If you are writing generic code that needs to handle both arrays and lists, use .size() – it works on everything. This is one reason Groovy developers prefer lists over arrays in most situations. For more on working with arrays, see our array manipulation post.
Example 10: Null Safety with the ?. Operator
What we’re doing: Handling null collections safely when checking size, using Groovy’s safe navigation operator.
Example 10: Null Safety
// Without null safety - NullPointerException!
List nullList = null
try {
println nullList.size()
} catch (NullPointerException e) {
println "Caught NPE: ${e.message}"
}
// With safe navigation operator ?.
println "Safe size: ${nullList?.size()}" // null
println "Safe with default: ${nullList?.size() ?: 0}" // 0
// Practical example: API response handling
def parseResponse(Map response) {
def items = response?.data?.items
def count = items?.size() ?: 0
println "Found ${count} items"
return count
}
// Normal response
parseResponse([data: [items: ['a', 'b', 'c']]])
// Missing items key
parseResponse([data: [:]])
// Null response
parseResponse(null)
// Safe counting with null elements
def mixedList = [1, null, 3, null, 5, null]
println "\nTotal elements: ${mixedList.size()}"
println "Non-null elements: ${mixedList.count { it != null }}"
println "Null elements: ${mixedList.count { it == null }}"
println "Compact (non-null): ${mixedList.findAll { it != null }.size()}"
// Null-safe isEmpty check
String nullString = null
println "\nNull string empty? ${nullString?.isEmpty()}"
println "With Elvis: ${nullString?.isEmpty() ?: true}"
Output
Caught NPE: Cannot invoke method size() on null object Safe size: null Safe with default: 0 Found 3 items Found 0 items Found 0 items Total elements: 6 Non-null elements: 3 Null elements: 3 Compact (non-null): 3 Null string empty? null With Elvis: true
What happened here: Calling .size() on a null reference throws a NullPointerException. The safe navigation operator ?. returns null instead of throwing. Combine it with the Elvis operator ?: to provide a default value like 0. This pattern – collection?.size() ?: 0 – is the idiomatic Groovy way to safely get a collection’s length. You will see it everywhere in Grails controllers and service classes. Also note that .size() counts null elements too, so use .count { it != null } if you only want non-null items.
Difference Between length and size()
This question comes up constantly, so let us settle it once and for all. Here is a detailed comparison based on the Groovy GDK collections documentation:
| Feature | .length | .size() | .length() |
|---|---|---|---|
| Type | Property (field) | Method | Method |
| Works on arrays | Yes | Yes (GDK) | No |
| Works on lists | No | Yes | No |
| Works on maps | No | Yes | No |
| Works on strings | No | Yes (GDK) | Yes |
| Works on sets | No | Yes | No |
| Parentheses | No | Yes | Yes |
| Origin | Java | Java + GDK | Java |
| Null safe with ?. | No | Yes | Yes |
Bottom line: Use .size() in Groovy code. It works on everything and keeps your code consistent. Reserve .length for cases where you specifically need to interact with Java arrays and want to make that intent clear.
Best Practice
// Avoid: inconsistent int[] arr = [1, 2, 3] String str = "hello" List list = [1, 2, 3] println arr.length // property println str.length() // method with () println list.size() // different method name // Prefer: consistent with size() println arr.size() // works println str.size() // works println list.size() // works
Output
3 5 3 3 5 3
Edge Cases and Best Practices
Best Practices Summary
DO:
- Use
.size()everywhere for consistency – it works on arrays, lists, maps, sets, strings, and ranges - Use
?.size() ?: 0for null-safe length checks - Use
.isEmpty()instead of.size() == 0for readability - Use Groovy truth (
if (list)) for quick non-empty checks - Use
.count{}when you need to count elements matching a condition
DON’T:
- Call
.size()or.lengthon null without the?.operator - Assume
.lengthon a pre-allocated array means it has that many real values - Mix
.length,.length(), and.size()in the same codebase – pick one approach - Forget that
.count(value)counts exact matches while.count{closure}counts by condition
Pro Tip: When working with sets, remember that duplicates are removed automatically. So
[1, 2, 2, 3, 3, 3] as Setwill have a.size()of 3, not 6. See our Groovy Set tutorial for more details.
Performance Considerations
All three approaches – .length, .size(), and .length() – are O(1) constant time operations. They return a stored value rather than counting elements, so performance is not a concern regardless of collection size.
Performance Comparison
def bigList = (1..1_000_000).toList()
int[] bigArray = (1..1_000_000) as int[]
// All are O(1) - instant regardless of size
def start1 = System.nanoTime()
def s1 = bigArray.length
def time1 = System.nanoTime() - start1
def start2 = System.nanoTime()
def s2 = bigArray.size()
def time2 = System.nanoTime() - start2
def start3 = System.nanoTime()
def s3 = bigList.size()
def time3 = System.nanoTime() - start3
println "array.length: ${s1} (${time1}ns)"
println "array.size(): ${s2} (${time2}ns)"
println "list.size(): ${s3} (${time3}ns)"
// count() with closure is O(n) - it checks every element
def start4 = System.nanoTime()
def s4 = bigList.count { it > 500_000 }
def time4 = System.nanoTime() - start4
println "list.count{}: ${s4} (${time4}ns) - O(n)"
Output
array.length: 1000000 (~500ns)
array.size(): 1000000 (~800ns)
list.size(): 1000000 (~400ns)
list.count{}: 500000 (~45000000ns) - O(n)
The important takeaway: .size() and .length are always fast. But .count{} iterates through every element, so it is O(n). On a million-element list, .size() takes nanoseconds while .count{} takes milliseconds. Use .count{} when you need filtered counts, but do not use it as a substitute for .size() when you just want the total.
Conclusion
Getting the Groovy array length is simple once you know the right tool for the job. We covered 10 examples spanning arrays, lists, maps, strings, multidimensional structures, conditional counting, and null safety. The patterns here will cover virtually every scenario you encounter in real Groovy projects.
If you take only one thing from this post, let it be this: use .size() everywhere. It works on every collection type, it is consistent, and it makes your code easier to read and maintain. Pair it with ?. for null safety and .count{} for conditional counts, and you have the full toolkit.
Next up, we will explore Groovy Sets – collections that automatically eliminate duplicates and offer unique size behaviors.
Summary
.lengthis a property on Java arrays – no parentheses, returns fixed capacity.size()is the universal GDK method – works on arrays, lists, maps, sets, strings, and ranges.length()is a method on strings – equivalent to.size().count()counts matching elements – accepts a value or a closure- Always use
?.size() ?: 0when the collection might be null
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 Set – Unique Collections Made Easy
Frequently Asked Questions
How do I get the length of an array in Groovy?
Use the .length property for Java arrays (e.g., int[] arr = [1,2,3]; println arr.length) or the .size() method which works on all collection types. The GDK adds size() to arrays, so arr.size() and arr.length return the same value. For consistency, most Groovy developers prefer .size().
What is the difference between .length and .size() in Groovy?
The .length is a Java property that only works on arrays. The .size() is a method that works on arrays, lists, maps, sets, strings, and ranges. On arrays, both return the same value. The key difference is that .length is a property (no parentheses) while .size() is a method call. Use .size() for portability across types.
How do I count elements matching a condition in Groovy?
Use the .count() method with a closure. For example: [1,2,3,4,5].count { it > 3 } returns 2. You can also pass a specific value: ['a','b','a'].count('a') returns 2. For more complex filtering, use .findAll{}.size() which also gives you the matching elements.
How do I safely get the size of a null collection in Groovy?
Use the safe navigation operator with the Elvis operator: collection?.size() ?: 0. The ?. operator returns null instead of throwing a NullPointerException when the collection is null, and the ?: operator provides a default value of 0. This is the idiomatic Groovy pattern for null-safe size checks.
Does .size() work on Groovy strings?
Yes. Groovy’s GDK adds a .size() method to String that returns the same value as the native .length() method. So ‘hello’.size() and ‘hello’.length() both return 5. Using .size() on strings lets you write consistent code that works the same way on strings, arrays, lists, and maps.
Related Posts
Previous in Series: Groovy Array Manipulation – Add, Remove, and Transform
Next in Series: Groovy Set – Unique Collections Made Easy
Related Topics You Might Like:
- Groovy List Tutorial – The Complete Guide
- Groovy Array Manipulation – Add, Remove, and Transform
- Groovy Set – Unique Collections Made Easy
This post is part of the Groovy & Grails Cookbook series on TechnoScripts.com

No comment