21

Groovy supports a literal syntax for creating a StringBuilder/StringBuffer instead of the usual

def sb = new StringBuilder()

However, I can't seem to remember (or find on Google) the correct syntax.

Dónal
  • 181,534
  • 169
  • 555
  • 808

4 Answers4

26

To get a StringBuffer in a single step, you could use

def sb = 'Hello'<<''

or even:

def sb = ''<<'' //4 single quotes, not double quotes

for an initially empty one.

I think (but I could be wrong) the reason for using a StringBuffer rather than a StringBuilder is to maintain compatibility with Java 1.4.

matt
  • 76,680
  • 8
  • 155
  • 193
16

To create a StringBuffer:

text = 'Hello '

To append:

text <<= 'World!'

And this might help some more.

willkil
  • 1,539
  • 1
  • 20
  • 31
omerkudat
  • 8,903
  • 4
  • 31
  • 42
  • 2
    It seems that that text is converted from a String to a StringBuilder only when the '<<=' operator is used, correct? Also, it's actually a StringBuffer not a StringBuilder – Dónal Nov 25 '09 at 15:20
  • 1
    Yes, in fact my example might be overly simplistic. You do need to convert and reassign to StringBuffer, as such the `<<=` operator. Later you can just use `< – omerkudat Nov 25 '09 at 15:30
14

I've just played with StringBuilder / StringBuffer in Groovy.

Some examples below:

// << operator example
def year = StringBuilder.newInstance()
year << 2
year << "0"
year << '1' << 4
assert year.toString() == "2014"

// You can use with operator
def month = StringBuilder.newInstance()
month.with {
    append "0"
    append '5'
}
assert month.toString() == "05"

// or just append String like in Java or you can leave parenthesis
def day = StringBuilder.newInstance()
day.append "1"
day.append('1')
assert day.toString() == '11'

// It's nice to know, that we can use StringBuilder directly in GString
def date = "$year-${month}-$day"
assert date == "2014-05-11"

Note: Use StringBuilder when it is used only by one thread. StringBuilder provides an API compatible with StringBuffer. StringBuffer is synchronized, StringBuilder is not. Check this link for more info.

Community
  • 1
  • 1
Michal Z m u d a
  • 5,082
  • 3
  • 41
  • 37
  • There's nothing special about using StringBuilder directly in GString: "[any Groovy expression is valid](http://groovy-lang.org/syntax.html#_string_interpolation)". The [official documentation](http://groovy-lang.org/syntax.html#_string_interpolation) shows `"The sum of 2 and 3 equals ${2 + 3}"` as an example. – willkil Mar 11 '19 at 15:46
1

String.leftShift() creates a StringBuffer.

AFAICS, you cannot create a StringBuilder via groovy syntax sugar. You can only create a StringBuilder explicitly. No operator overload on String or GString creates a StringBuilder that you can explicitly use. Java String concatenation might create a StringBuilder, but that instance wouldn't be usable in your code.

At the time of writing this answer:

  • Another answer said to use <<=. <<= is merely a java compound assignment that uses <<. In particular, there is no method for overloading <<=.
  • The accepted answer said to use ''<<'' //4 single quotes, not double quotes. Double quotes work fine, at least on modern groovy.

The following code shows that we always get a StringBuffer, not a StringBuilder, for the result of various combinations of << vs <<= and "" vs '':

def ls = ''<<''
println ls.class
def lse = ''
lse <<=''
println lse.class

ls = ""<<''
println ls.class
lse = ""
lse <<=''
println lse.class

ls = ''<<""
println ls.class
lse = ''
lse <<=""
println lse.class

ls = ""<<""
println ls.class
lse = ""
lse <<=""
println lse.class

prints:

class java.lang.StringBuffer
class java.lang.StringBuffer
class java.lang.StringBuffer
class java.lang.StringBuffer
class java.lang.StringBuffer
class java.lang.StringBuffer
class java.lang.StringBuffer
class java.lang.StringBuffer
willkil
  • 1,539
  • 1
  • 20
  • 31