简体   繁体   English

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

[英]Groovy: Add prefix to each String in a List

Given is the following list: 给出以下列表:

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

Now I want to create one String out of this list in the following format: 现在我想以下列格式从这个列表中创建一个String:

"pre/test1 pre/test2 pre/test3"

So I thought I would go the following way: 所以我想我会采取以下方式:

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

However, this leads to the following output: 但是,这会导致以下输出:

"test1 test2 test3"

(Note the missing prefixes.) (注意缺少的前缀。)
How can I achieve the desired string concatenation in Groovy? 如何在Groovy中实现所需的字符串连接?

def joined = ["test1", "test2", "test3"].collect { "pre/$it" }.join(' ')

each返回未修改的集合 - 而collect返回带有修改内容的集合。

For large lists (clearly not the case here) it is more efficient to form the string directly: 对于大型列表(这里显然不是这种情况),直接形成字符串更有效:

 def sb = ["test1", "test2", "test3"].inject(new StringBuilder()) { builder, value -> builder << "pre/${value} " } sb.setLength(sb.size() - 1) // to trim the trailing space 

It turns out that rather the opposite is the case. 事实证明,情况正好相反。 Here are some test runs using 10 million elements, tracking CPU and Real time across multiple runs: 以下是一些使用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
}

And here are the results: 以下是结果:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM