4

I am attempting to call the Apache Commons StringUtils.join() method from within a Groovy class. I want to concatenate 3 strings (part1, part2, and part3).

Why doesn't this work?

def path = StringUtils.join([part1, part2, part3]) //1

But the following line works:

def path = StringUtils.join([part1, part2, part3] as String[]) //2

A follow up question. Why does this work? I am using StringUtils v 2.6, so it does not have a varargs method. Does groovy always convert method parameters to an array?

def path = StringUtils.join(part1, part2, part3)  //3

This is largely a curiosity question. I am not going to use StringUtils because I posted a separate question yesterday and found a better solution. However, I would still like to understand why technique #1 does not work, yet #3 does work.

1
  • For #1, the result is a String representation of the array, not the actual elements of the array concatenated together. It appear the array is converted to a String before it is sent to the join() method. Commented Mar 20, 2012 at 15:54

1 Answer 1

8

So, to show what is happening, let's write a script and show what output we get:

@Grab( 'commons-lang:commons-lang:2.6' )
import org.apache.commons.lang.StringUtils

def (part1,part2,part3) = [ 'one', 'two', 'three' ]

def path = StringUtils.join( [ part1, part2, part3 ] )
println "1) $path"

path = StringUtils.join( [ part1, part2, part3 ] as String[] )
println "2) $path"

path = StringUtils.join( part1, part2, part3 )
println "3) $path"

This prints:

1) [one, two, three]
2) onetwothree
3) onetwothree

Basically, the only one of your method calls that matches a signature in the StringUtils class is 2), as it matches the Object[] method definition. For the other two, Groovy is picking the best match that is can find for your method call.

For both 1) and 3), it's doing the same thing. Wrapping the parameters as an Object[] and calling the same method as 2)

For 3) this is fine, as you get an Object[] with 3 elements, but for 1), you get an Object[] with one element; your List.

A way of getting it to work with the List parameter, would be to use the spread operator like so:

path = StringUtils.join( *[ part1, part2, part3 ] )
println "4) $path"

Which would then print:

4) onetwothree

As expected (it would put all the elements of the list in as separate parameters, and these would then be put into an Object[] with three elements as in example 3)

Sign up to request clarification or add additional context in comments.

1 Comment

This answer is phenomenal. I wish I could provide multiple upvotes. The description is clean and thorough. Plus, you mentioned the spread operator. Thanks tim_yates.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.