简体   繁体   中英

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:

"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?

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:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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