鉴于以下列表:
List<String> list = ["test1", "test2", "test3"]
现在我想用以下格式从这个列表中创建一个String:
"pre/test1 pre/test2 pre/test3"
所以我想我会采取以下方式:
println list.each { "pre/$it" }.join(' ')
然而,这导致以下输出:
"test1 test2 test3"
(注意缺少的前缀。)
如何在Groovy中实现所需的字符串连接?
答案 0 :(得分:10)
def joined = ["test1", "test2", "test3"].collect { "pre/$it" }.join(' ')
each
返回未修改的集合 - 而collect
返回带有修改内容的集合。
答案 1 :(得分:1)
对于大型列表(这里显然不是这种情况),直接形成字符串更有效:
def sb = ["test1", "test2", "test3"].inject(new StringBuilder()) { builder, value ->
builder << "pre/${value} "
}
sb.setLength(sb.size() - 1) // to trim the trailing space
事实证明,情况正好相反。以下是使用1000万个元素的一些测试运行,跨多个运行跟踪CPU和实时:
import java.lang.management.ManagementFactory
def threadMX = ManagementFactory.threadMXBean
assert threadMX.currentThreadCpuTimeSupported
threadMX.threadCpuTimeEnabled = true
def timeCPU = { Closure c ->
def start = threadMX.currentThreadCpuTime
def result = c.call()
def end = threadMX.currentThreadCpuTime
println "CPU time: ${(end - start)/1000000000} s"
}
def timeReal = { Closure c ->
def start = System.currentTimeMillis()
def result = c.call(args)
def end = System.currentTimeMillis()
println "Elapsed time: ${(end - start)/1000} s"
result
}
def theList = (0..<10000000). collect { it.toString() }
[CPU:timeCPU, Real:timeReal].each { label, time ->
println "\n\n$label Time"
print ("Mine: ".padLeft(20))
def s2 = time {
def sb = theList.inject(new StringBuilder()) { builder, value ->
builder << "pre/${value} "
}
sb.setLength(sb.size() - 1)
sb.toString()
}
print ("cfrick's: ".padLeft(20))
def s3 = time {
def sb = theList.inject(new StringBuilder()) { builder, value ->
builder << "pre/" << value << " "
}
sb.setLength(sb.size() - 1)
sb.toString()
}
print ("Opal's: ".padLeft(20))
def s1 = time { theList.collect { "pre/${it}" }.join(" ") }
print "Opal's w/o GString: "
def s4 = time { theList.collect { "pre/" + it }.join(" ") }
assert s1 == s2 && s2 == s3 && s3 == s4
}
以下是结果:
CPU Time
Mine: CPU time: 12.8076821 s
cfrick's: CPU time: 2.1684139 s
Opal's: CPU time: 3.5724229 s
Opal's w/o GString: CPU time: 3.1356201 s
Real Time
Mine: Elapsed time: 15.826 s
cfrick's: Elapsed time: 3.587 s
Opal's: Elapsed time: 8.906 s
Opal's w/o GString: Elapsed time: 6.296 s