Groovy:为List中的每个String添加前缀

时间:2014-10-29 15:53:20

标签: groovy

鉴于以下列表:

List<String> list = ["test1", "test2", "test3"]

现在我想用以下格式从这个列表中创建一个String:

"pre/test1 pre/test2 pre/test3"

所以我想我会采取以下方式:

println list.each { "pre/$it" }.join(' ')

然而,这导致以下输出:

"test1 test2 test3"

(注意缺少的前缀。)
如何在Groovy中实现所需的字符串连接?

2 个答案:

答案 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