15 Essential Groovy String Methods Every Developer Must Know

Groovy strings are explored here with 15 practical examples covering GStrings, multiline, trim, split, replace, and more. Complete tutorial tested on Groovy 5.x.

“In programming, strings are the glue that holds user-facing applications together. Master strings, and you master half the job.”

Bjarne Stroustrup, The C++ Programming Language

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

If there’s one topic every Groovy developer needs to get right, it’s Groovy strings. Strings pop up everywhere – user input, database queries, API responses, log messages, file paths. And Groovy handles strings in ways that will genuinely make you enjoy working with text.

Unlike Java, where string manipulation often means chaining StringBuilder calls or writing verbose format strings, Groovy gives you GStrings for interpolation, triple-quoted strings for multi-line content, slashy strings for regex, and dozens of extra methods through the GDK. This Groovy string tutorial covers it all.

This post covers every string type Groovy offers, 15+ practical string methods, and the common pitfalls that trip up beginners. If you need specific string operations, we have dedicated posts on substrings, take(), drop(), and string comparison.

What Are Groovy Strings?

Groovy has two main string types: java.lang.String (plain strings) and groovy.lang.GString (interpolated strings). On top of that, it offers multiple ways to create them – single quotes, double quotes, triple quotes, and slashy strings.

According to the official Groovy syntax documentation, Groovy supports five string literal forms. Each serves a different purpose, and knowing when to use which one makes your code cleaner and more readable.

Key Points:

  • Single-quoted strings ('hello') are plain java.lang.String
  • Double-quoted strings ("hello ${name}") are GStrings when they contain interpolation
  • Triple single-quoted ('''...''') are multiline plain strings
  • Triple double-quoted ("""...""") are multiline GStrings
  • Slashy strings (/pattern/) are ideal for regular expressions
  • Groovy adds 60+ extra methods to Java’s String class through the GDK

5 Types of Strings in Groovy

TypeSyntaxInterpolationMultilineJava Type
Single-quoted'hello'NoNojava.lang.String
Double-quoted"hello ${x}"YesNoGString (or String if no $)
Triple single'''hello'''NoYesjava.lang.String
Triple double"""hello ${x}"""YesYesGString
Slashy/pattern/YesYesGString (or String if no $)

All 5 String Types

def name = "World"

// 1. Single-quoted - plain java.lang.String
def s1 = 'Hello, World!'
println "${s1} → ${s1.getClass().name}"

// 2. Double-quoted - GString with interpolation
def s2 = "Hello, ${name}!"
println "${s2} → ${s2.getClass().name}"

// 3. Triple single-quoted - multiline plain String
def s3 = '''Line 1
Line 2
Line 3'''
println "${s3} → ${s3.getClass().name}"

// 4. Triple double-quoted - multiline GString
def s4 = """Hello, ${name}!
Welcome to Groovy."""
println "${s4} → ${s4.getClass().name}"

// 5. Slashy string - great for regex
def s5 = /Hello, ${name}!/
println "${s5} → ${s5.getClass().name}"

Output

Hello, World! → java.lang.String
Hello, World! → org.codehaus.groovy.runtime.GStringImpl
Line 1
Line 2
Line 3 → java.lang.String
Hello, World!
Welcome to Groovy. → org.codehaus.groovy.runtime.GStringImpl
Hello, World! → org.codehaus.groovy.runtime.GStringImpl

Notice how double-quoted strings without ${} become plain Strings, but the moment you add interpolation, they become GStrings. This is important to know because some APIs (like Map keys) behave differently with GStrings vs Strings.

Syntax and Basic Usage

String Creation

Creating Strings

// Literal strings
def str1 = 'Simple string'
def str2 = "GString: ${2 + 3}"

// From constructor
def str3 = new String("From constructor")

// From char array
def str4 = new String(['H', 'i'] as char[])

// From bytes
def str5 = new String([72, 101, 108, 108, 111] as byte[])

println str1
println str2
println str3
println str4
println str5

Output

Simple string
GString: 5
From constructor
Hi
Hello

Key String Methods (Quick Reference)

MethodDescriptionExampleResult
length() / size()String length"hello".size()5
toUpperCase()Convert to uppercase"hello".toUpperCase()HELLO
toLowerCase()Convert to lowercase"HELLO".toLowerCase()hello
trim()Remove whitespace" hi ".trim()hi
contains()Check if contains"hello".contains("ell")true
replace()Replace substring"hello".replace("l","r")herro
split()Split into array"a,b,c".split(",")[a, b, c]
reverse()Reverse string"hello".reverse()olleh
take(n)First n chars"hello".take(3)hel
drop(n)Skip first n chars"hello".drop(2)llo

15 Practical String Examples

Example 1: String Concatenation

What we’re doing: Combining strings in different ways.

Example 1: Concatenation

def first = "Hello"
def last = "World"

// Method 1: Plus operator
println first + ", " + last + "!"

// Method 2: GString interpolation (preferred)
println "${first}, ${last}!"

// Method 3: concat()
println first.concat(", ").concat(last).concat("!")

// Method 4: StringBuilder (for heavy concatenation)
def sb = new StringBuilder()
sb.append(first).append(", ").append(last).append("!")
println sb.toString()

Output

Hello, World!
Hello, World!
Hello, World!
Hello, World!

What happened here: All four methods produce the same result. In Groovy, GString interpolation (Method 2) is the preferred way – it’s the most readable and performs well. Only use StringBuilder for loops that concatenate hundreds or thousands of strings.

Example 2: GString Interpolation with Expressions

What we’re doing: Using expressions inside ${}.

Example 2: Expressions in GStrings

def price = 49.99
def qty = 3

println "Total: \$${price * qty}"
println "Discount: \$${(price * qty * 0.1).round(2)}"
println "Date: ${new Date().format('yyyy-MM-dd')}"
println "Random: ${new Random().nextInt(100)}"
println "Uppercase: ${'hello'.toUpperCase()}"

Output

Total: $149.97
Discount: $15.00
Date: 2026-03-08
Random: 42
Uppercase: HELLO

What happened here: You can put any Groovy expression inside ${} – method calls, arithmetic, object creation. The dollar sign for currency needs escaping with \$ to avoid being treated as interpolation. Learn more about GStrings in our GString guide.

Example 3: Multiline Strings

What we’re doing: Creating multiline strings with triple quotes.

Example 3: Multiline Strings

def name = "Alice"

// Triple single quotes - no interpolation
def sql = '''
SELECT *
FROM users
WHERE active = true
ORDER BY name
'''

// Triple double quotes - with interpolation
def email = """
Dear ${name},

Thank you for registering.
Your account is now active.

Best regards,
TechnoScripts Team
"""

println sql.trim()
println "---"
println email.trim()

Output

SELECT *
FROM users
WHERE active = true
ORDER BY name
---
Dear Alice,

Thank you for registering.
Your account is now active.

Best regards,
TechnoScripts Team

What happened here: Triple-quoted strings preserve all line breaks and formatting. Use triple single quotes for SQL, config files, and any text without variables. Use triple double quotes when you need interpolation. Both types are used extensively in Grails for HQL queries and email templates.

Example 4: String Padding and Centering

What we’re doing: Formatting strings with padding methods from the GDK.

Example 4: Padding

def items = ["Apple", "Banana", "Cherry"]
def prices = [1.50, 0.75, 2.25]

println "ITEM".padRight(15) + "PRICE"
println "-" * 20

items.eachWithIndex { item, i ->
    println item.padRight(15) + "\$${prices[i]}"
}

println ""
println "centered".center(20, '=')
println "left".padRight(20, '.')
println "right".padLeft(20, '.')

Output

ITEM           PRICE
--------------------
Apple          $1.50
Banana         $0.75
Cherry         $2.25

======centered======
left................
...............right

What happened here: Groovy’s GDK adds padRight(), padLeft(), and center() to String. The * operator repeats a string – "-" * 20 creates twenty dashes. These are perfect for formatting console output and reports.

Example 5: String to Number Conversion

What we’re doing: Converting strings to various number types.

Example 5: String to Number

def numStr = "42"
def decStr = "3.14"

println "toInteger: ${numStr.toInteger()} (${numStr.toInteger().getClass().simpleName})"
println "toLong: ${numStr.toLong()} (${numStr.toLong().getClass().simpleName})"
println "toFloat: ${decStr.toFloat()} (${decStr.toFloat().getClass().simpleName})"
println "toDouble: ${decStr.toDouble()} (${decStr.toDouble().getClass().simpleName})"
println "toBigDecimal: ${decStr.toBigDecimal()} (${decStr.toBigDecimal().getClass().simpleName})"

// Safe conversion - returns null instead of exception
println "isNumber: ${'abc'.isNumber()}"
println "isNumber: ${'123'.isNumber()}"
println "isInteger: ${'42'.isInteger()}"

Output

toInteger: 42 (Integer)
toLong: 42 (Long)
toFloat: 3.14 (Float)
toDouble: 3.14 (Double)
toBigDecimal: 3.14 (BigDecimal)
isNumber: false
isNumber: true
isInteger: true

What happened here: Groovy adds conversion methods directly to String. Always check with isNumber() or isInteger() before converting to avoid exceptions. For a complete guide on conversions, see Groovy String To Integer.

Example 6: Substring and take/drop

What we’re doing: Extracting parts of strings using multiple approaches.

Example 6: Extracting Parts

def text = "Hello, World!"

// Java's substring
println text.substring(0, 5)    // Hello
println text.substring(7)       // World!

// Groovy's take/drop (safer - no IndexOutOfBounds)
println text.take(5)            // Hello
println text.drop(7)            // World!

// Groovy subscript operator
println text[0..4]              // Hello
println text[7..-1]             // World!
println text[-6..-1]            // orld!

// take is safe with lengths > string size
println "Hi".take(100)          // Hi (no exception!)

Output

Hello
World!
Hello
World!
Hello
World!
World!
Hi

What happened here: Groovy gives you three ways to extract substrings. The subscript operator (text[0..4]) uses ranges and supports negative indices. The take() method is the safest – it never throws an exception, even if you request more characters than the string contains. More details in our substring guide and take() guide.

Example 7: Replace and ReplaceAll

What we’re doing: Replacing text within strings.

Example 7: Replace

def text = "The quick brown fox jumps over the lazy dog"

// Simple replace
println text.replace("fox", "cat")

// Replace first occurrence
println text.replaceFirst("the", "THE")

// Replace with regex
println text.replaceAll(/[aeiou]/, "*")

// Groovy's tr (transliterate - like Unix tr command)
println "hello".tr("aeiou", "*")
println "Hello World".tr("a-z", "A-Z")

Output

The quick brown cat jumps over the lazy dog
The quick brown fox jumps over THE lazy dog
Th* q**ck br*wn f*x j*mps *v*r th* l*zy d*g
h*ll*
HELLO WORLD

What happened here: replace() does literal replacement. replaceAll() uses regex patterns. And Groovy’s tr() method transliterates characters – like Unix’s tr command.

Example 8: Split and Tokenize

What we’re doing: Breaking strings into pieces.

Example 8: Split and Tokenize

def csv = "apple,banana,,cherry,,"

// split() - keeps empty strings
def parts1 = csv.split(",")
println "split: ${parts1 as List} (${parts1.length} elements)"

// tokenize() - removes empty strings (Groovy GDK)
def parts2 = csv.tokenize(",")
println "tokenize: ${parts2} (${parts2.size()} elements)"

// Split with regex
def words = "Hello   World   Groovy".split(/\s+/)
println "regex split: ${words as List}"

// Split with limit
def limited = "a:b:c:d:e".split(":", 3)
println "limited: ${limited as List}"

Output

split: [apple, banana, , cherry] (4 elements)
tokenize: [apple, banana, cherry] (3 elements)
regex split: [Hello, World, Groovy]
limited: [a, b, c:d:e]

What happened here: The key difference – split() returns a String array and keeps empty elements. tokenize() returns a List and skips empties. Choose based on whether empty values matter to your logic. We cover this in detail in the split and tokenize posts.

Example 9: Trim and Strip

What we’re doing: Removing whitespace from strings.

Example 9: Trimming

def messy = "   Hello, World!   "

println "'${messy.trim()}'"          // Both sides
println "'${messy.stripLeading()}'"  // Left only (Java 11+)
println "'${messy.stripTrailing()}'" // Right only (Java 11+)

// Groovy's stripIndent - removes common leading whitespace
def indented = """
    Line 1
    Line 2
        Line 3 (indented more)
    Line 4
""".stripIndent().trim()
println indented

Output

'Hello, World!'
'Hello, World!   '
'   Hello, World!'
Line 1
Line 2
    Line 3 (indented more)
Line 4

What happened here: stripIndent() is a Groovy GDK method that finds the smallest indentation across all lines and removes it. Incredibly useful when you have triple-quoted strings inside indented code blocks.

Example 10: String Comparison

What we’re doing: Comparing strings using different methods.

Example 10: Comparison

def a = "Hello"
def b = "hello"
def c = "Hello"

// equals (case-sensitive)
println "a == c: ${a == c}"        // true (Groovy uses equals(), not identity!)
println "a == b: ${a == b}"        // false

// Case-insensitive
println "equalsIgnoreCase: ${a.equalsIgnoreCase(b)}"  // true

// Spaceship operator for comparison
println "a <=> b: ${a <=> b}"      // negative (H < h in ASCII)
println "a <=> c: ${a <=> c}"      // 0 (equal)

// Identity check (same object in memory)
println "a.is(c): ${a.is(c)}"      // may be true (string pool)

Output

a == c: true
a == b: false
equalsIgnoreCase: true
a <=> b: -1
a <=> c: 0
a.is(c): true

What happened here: In Groovy, == calls equals(), not reference comparison like Java. This means == is safe for string comparison – no need for .equals(). For identity comparison, use .is(). Full details in Groovy Compare Strings.

Example 11: String Reverse

What we’re doing: Reversing strings and checking palindromes.

Example 11: Reverse

println "Hello".reverse()
println "12345".reverse()

// Palindrome check
def isPalindrome = { str ->
    def clean = str.toLowerCase().replaceAll(/[^a-z0-9]/, '')
    clean == clean.reverse()
}

println "madam: ${isPalindrome('madam')}"
println "hello: ${isPalindrome('hello')}"
println "A man a plan a canal Panama: ${isPalindrome('A man a plan a canal Panama')}"

Output

olleH
54321
madam: true
hello: false
A man a plan a canal Panama: true

What happened here: Groovy’s reverse() is a GDK method added to String. Combined with replaceAll() and a closure, you get a clean palindrome checker in just a few lines.

Example 12: String Multiply and Repeat

What we’re doing: Repeating strings using the multiply operator.

Example 12: Multiply

println "Ha" * 3
println "-" * 40
println "abc " * 4

// Building a simple progress bar
def progress = 7
def total = 10
def bar = "█" * progress + "░" * (total - progress)
println "[${bar}] ${progress * 10}%"

Output

HaHaHa
----------------------------------------
abc abc abc abc
[███████░░░] 70%

What happened here: Groovy overloads the * operator for strings. "abc" * 3 repeats the string 3 times. This is much cleaner than Java’s String.repeat(3) (Java 11+) or manual loops.

Example 13: Regular Expression Matching

What we’re doing: Using Groovy’s regex operators with strings.

Example 13: Regex Matching

def email = "user@example.com"
def phone = "123-456-7890"

// Match operator (==~) - returns boolean
println "Valid email: ${email ==~ /[\w.]+@[\w.]+\.\w+/}"
println "Valid phone: ${phone ==~ /\d{3}-\d{3}-\d{4}/}"

// Find operator (=~) - returns Matcher
def text = "Call 123-456-7890 or 098-765-4321"
def matcher = text =~ /\d{3}-\d{3}-\d{4}/
println "Found ${matcher.count} phone numbers"
matcher.each { println "  ${it}" }

Output

Valid email: true
Valid phone: true
Found 2 phone numbers
  123-456-7890
  098-765-4321

What happened here: Groovy’s ==~ operator checks for an exact match (returns boolean). The =~ operator finds all matches (returns a Matcher). Slashy strings (/pattern/) make regex patterns clean – no double-backslash escaping needed.

Example 14: String Case Conversion

What we’re doing: Converting between different case formats.

Example 14: Case Conversion

def text = "hello world groovy"

println text.toUpperCase()
println text.toLowerCase()
println text.capitalize()             // First char uppercase

// Title Case - capitalize each word
println text.split(' ').collect { it.capitalize() }.join(' ')

// Groovy's uncapitalize
println "HelloWorld".uncapitalize()

Output

HELLO WORLD GROOVY
hello world groovy
Hello world groovy
Hello World Groovy
helloWorld

What happened here: capitalize() and uncapitalize() are Groovy GDK methods. Title case isn’t built-in, but it’s a one-liner with split, collect, and join.

Example 15: String Iteration

What we’re doing: Iterating over characters in a string.

Example 15: String Iteration

def word = "Groovy"

// each character
word.each { ch -> print "${ch}-" }
println()

// eachWithIndex
word.eachWithIndex { ch, i -> print "${i}:${ch} " }
println()

// collect - transform each character
println word.toList().collect { it.toUpperCase() }

// Count specific characters
def vowels = word.toList().count { it.toLowerCase() in ['a','e','i','o','u'] }
println "Vowels in '${word}': ${vowels}"

// Unique characters
println "Unique chars: ${word.toList().unique()}"

Output

G-r-o-o-v-y-
0:G 1:r 2:o 3:o 4:v 5:y
[G, R, O, O, V, Y]
Vowels in 'Groovy': 2
Unique chars: [G, r, o, v, y]

What happened here: Strings in Groovy can be iterated like collections. Methods like each() and eachWithIndex() work directly on strings. For collect() and count() with closures, convert to a list first with toList().

GString Interpolation Details

There’s a subtle but important detail about GStrings: they evaluate lazily in some cases.

GString Lazy Evaluation

// GString with a closure - evaluates lazily
def counter = 0
def message = "Count: ${-> ++counter}"

println message  // evaluates now
println message  // evaluates again - counter incremented!
println message  // and again!

// GString vs String for Map keys (gotcha!)
def map = [:]
def key = "name"
map["${key}"] = "Alice"   // GString key
map[key] = "Bob"           // String key

println map.size()          // 2! Different keys because GString != String
println map

Output

Count: 1
Count: 2
Count: 3
2
[name:Alice, name:Bob]

When you put a closure (${-> expr}) inside a GString, it re-evaluates every time the GString is used. And watch out for the map key gotcha – a GString key and a String key are different objects even if they contain the same text.

Deprecated vs Modern Approach

Old vs Modern String Operations

// Old way: Java-style string building
def name = "Alice"
def age = 30

// Deprecated approach (Java 5 style)
String old1 = String.format("Name: %s, Age: %d", name, age)
println old1

// Modern approach: GString
String modern1 = "Name: ${name}, Age: ${age}"
println modern1

// Old way: StringBuilder for simple concat
def old2 = new StringBuilder().append("Hello, ").append(name).toString()
println old2

// Modern approach: GString
def modern2 = "Hello, ${name}"
println modern2

Output

Name: Alice, Age: 30
Name: Alice, Age: 30
Hello, Alice
Hello, Alice

Migration Note: String.format() and StringBuilder still work in Groovy, but GString interpolation is preferred for readability. Only use StringBuilder for loop-heavy concatenation.

Edge Cases and Best Practices

Best Practices Summary

DO:

  • Use single quotes for static strings (no interpolation needed)
  • Use double quotes when you need ${} interpolation
  • Use triple quotes for multiline strings (SQL, templates, emails)
  • Use slashy strings for regex patterns
  • Use == for string comparison (it calls .equals())

DON’T:

  • Use GStrings as Map keys (they don’t equal String keys)
  • Concatenate strings in loops with + – use StringBuilder or collect().join()
  • Forget to escape $ in double-quoted strings when you mean literal dollar signs

Performance Considerations

For most string operations, performance is not a concern. But here are some tips for high-volume processing:

Performance Tips

// Slow: concatenation in a loop
def slow() {
    def result = ""
    1000.times { result += "x" }
    return result.length()
}

// Fast: StringBuilder in a loop
def fast() {
    def sb = new StringBuilder()
    1000.times { sb.append("x") }
    return sb.toString().length()
}

// Also fast: collect and join
def alsoFast() {
    return (1..1000).collect { "x" }.join()
}

println "All produce strings of length: ${slow()}"

Output

All produce strings of length: 1000

String concatenation with + creates a new String object every iteration – O(n²) performance. StringBuilder and collect/join are both O(n).

Common Pitfalls

Pitfall 1: GString vs String in Switch Statements

Switch Pitfall

def type = "admin"
def role = "${type}"  // This is a GString

switch (role) {
    case 'admin':     // This is a String
        println "Admin access granted"
        break
    default:
        println "No match"
}

Output

Admin access granted

This actually works because Groovy’s switch uses isCase() which handles GString/String comparison. But it’s still good practice to use .toString() on GStrings when exact type matching matters.

Pitfall 2: Single vs Double Quotes with Dollar Signs

Dollar Sign Pitfall

def price = 99.99

// Wrong - $ is literal in single quotes
println 'Price: $price'           // Price: $price

// Correct - interpolation with double quotes
println "Price: \$${price}"       // Price: $99.99

// Also correct - escape dollar for literal
println "Price: \$${price} USD"   // Price: $99.99 USD

Output

Price: $price
Price: $99.99
Price: $99.99 USD

Conclusion

We covered a lot of ground in this Groovy string tutorial – from the five string types to 15 practical examples, GString internals, and performance tips. Strings in Groovy are genuinely more pleasant to work with than in Java, thanks to GString interpolation, multiline strings, the GDK’s extra methods, and operator overloading.

The key things to remember: use single quotes for plain strings, double quotes for interpolation, triple quotes for multiline, and slashy strings for regex. And always use == for comparison – it’s safe in Groovy.

For deeper dives into specific string operations, check out the related posts below.

Summary

  • Groovy has 5 string types: single, double, triple-single, triple-double, and slashy
  • GStrings (double-quoted) support ${expression} interpolation
  • The GDK adds 60+ methods to String – reverse(), take(), drop(), capitalize(), and more
  • == is safe for string comparison in Groovy (calls .equals())
  • Use tokenize() instead of split() when you want to skip empty elements

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 String To Integer – All Conversion Methods

Frequently Asked Questions

What is the difference between String and GString in Groovy?

A String (single-quoted) is a plain java.lang.String with no interpolation. A GString (double-quoted with ${}) is a groovy.lang.GString that evaluates expressions at runtime. GStrings are automatically converted to Strings when needed, but they are different types internally.

How do I compare strings in Groovy?

Use the == operator. In Groovy, == calls .equals() (not reference comparison like Java), so it’s safe for string comparison. For case-insensitive comparison, use .equalsIgnoreCase(). For ordering, use the spaceship operator (<=>).

What are triple-quoted strings in Groovy?

Triple-quoted strings (''' or """) preserve line breaks and indentation. Use triple single-quotes for multiline text without interpolation (SQL, templates). Use triple double-quotes when you need ${} interpolation in multiline strings.

How do I convert a Groovy string to a number?

Use the built-in methods: toInteger(), toLong(), toFloat(), toDouble(), or toBigDecimal(). Always check first with isNumber() or isInteger() to avoid NumberFormatException. Example: ’42’.toInteger() returns 42.

What is a slashy string in Groovy?

A slashy string (/pattern/) is a string delimited by forward slashes. It’s primarily used for regular expressions because backslashes don’t need escaping. For example, /\d+/ matches digits – you write one backslash instead of Java’s double backslash.

Previous in Series: Groovy -e Command Line Option – Run Scripts Instantly

Next in Series: Groovy String To Integer – All Conversion Methods

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 *