Groovy literal StringBuilder/StringBuffer
Asked Answered
G

4

22

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.

Gad answered 25/11, 2009 at 14:56 Comment(1)
sb.append("text") will concatenate your stringsTops
C
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.

Chesterfield answered 25/11, 2009 at 16:14 Comment(2)
You would also use a StringBuffer in current Java versions if you need to concatenate strings thread-safelyGore
Double quotes work fine, at least on modern groovy.Recede
B
16

To create a StringBuffer:

text = 'Hello '

To append:

text <<= 'World!'

And this might help some more.

Builtin answered 25/11, 2009 at 15:4 Comment(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 StringBuilderGore
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 <<. Also you are right about the StringBuffer, which is how they allowed in-place character replacement using the [] operator.Builtin
B
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.

Briefcase answered 11/5, 2014 at 15:9 Comment(1)
There's nothing special about using StringBuilder directly in GString: "any Groovy expression is valid". The official documentation shows "The sum of 2 and 3 equals ${2 + 3}" as an example.Recede
R
2

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
Recede answered 11/3, 2019 at 17:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.