使用 Groovy 进行字符串连接 [英] String concatenation with Groovy

查看:19
本文介绍了使用 Groovy 进行字符串连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Groovy 中连接字符串的最佳(惯用)方法是什么?

What is the best (idiomatic) way to concatenate Strings in Groovy?

选项 1:

calculateAccountNumber(bank, branch, checkDigit, account) {
    bank + branch + checkDigit + account
}

选项 2:

calculateAccountNumber(bank, branch, checkDigit, account) {
    "$bank$branch$checkDigit$account"
}

我在旧的 Groovy 网站上建立了一个关于这个主题的有趣观点:你可以做但最好不要做的事情.

I've founded an interesting point about this topic in the old Groovy website: Things you can do but better leave undone.

与在 Java 中一样,您可以使用+"符号连接字符串.但是Java只需要+"表达式的两项中的一项是字符串,无论是在第一个还是在最后一个.爪哇将在+"的非字符串对象中使用 toString() 方法表达.但是在 Groovy 中,您应该确保第一项是安全的您的+"表达式以正确的方式实现了 plus() 方法,因为 Groovy 会搜索并使用它.在 Groovy GDK 中,只有 Number和 String/StringBuffer/Character 类有 plus() 方法实现连接字符串.为避免意外,请始终使用GStrings.

As in Java, you can concatenate Strings with the "+" symbol. But Java only needs that one of the two items of a "+" expression to be a String, no matter if it's in the first place or in the last one. Java will use the toString() method in the non-String object of your "+" expression. But in Groovy, you just should be safe the first item of your "+" expression implements the plus() method in the right way, because Groovy will search and use it. In Groovy GDK, only the Number and String/StringBuffer/Character classes have the plus() method implemented to concatenate strings. To avoid surprises, always use GStrings.

推荐答案

我总是采用第二种方法(使用 GString 模板),但是当像你这样有多个参数时,我倾向于将它们包装起来在 ${X} 中,因为我发现它更具可读性.

I always go for the second method (using the GString template), though when there are more than a couple of parameters like you have, I tend to wrap them in ${X} as I find it makes it more readable.

运行一些基准测试(使用 Nagai Masato 出色的 GBench 模块) 在这些方法上也表明模板比其他方法更快:

Running some benchmarks (using Nagai Masato's excellent GBench module) on these methods also shows templating is faster than the other methods:

@Grab( 'com.googlecode.gbench:gbench:0.3.0-groovy-2.0' )
import gbench.*

def (foo,bar,baz) = [ 'foo', 'bar', 'baz' ]
new BenchmarkBuilder().run( measureCpuTime:false ) {
  // Just add the strings
  'String adder' {
    foo + bar + baz
  }
  // Templating
  'GString template' {
    "$foo$bar$baz"
  }
  // I find this more readable
  'Readable GString template' {
    "${foo}${bar}${baz}"
  }
  // StringBuilder
  'StringBuilder' {
    new StringBuilder().append( foo )
                       .append( bar )
                       .append( baz )
                       .toString()
  }
  'StringBuffer' {
    new StringBuffer().append( foo )
                      .append( bar )
                      .append( baz )
                      .toString()
  }
}.prettyPrint()

这给了我机器上的以下输出:

That gives me the following output on my machine:

Environment
===========
* Groovy: 2.0.0
* JVM: Java HotSpot(TM) 64-Bit Server VM (20.6-b01-415, Apple Inc.)
    * JRE: 1.6.0_31
    * Total Memory: 81.0625 MB
    * Maximum Memory: 123.9375 MB
* OS: Mac OS X (10.6.8, x86_64) 

Options
=======
* Warm Up: Auto 
* CPU Time Measurement: Off

String adder               539
GString template           245
Readable GString template  244
StringBuilder              318
StringBuffer               370

因此,为了提高可读性和速度,我建议使用模板 ;-)

So with readability and speed in it's favour, I'd recommend templating ;-)

注意:如果您在 GString 方法的末尾添加 toString() 以使输出类型与其他指标相同,并使其成为更公平的测试,StringBuilderStringBuffer 在速度上优于 GString 方法.但是,由于 GString 可以在大多数情况下代替 String 使用(您只需要小心使用 Map 键和 SQL 语句),因此大多数情况下可以不进行最终转换

NB: If you add toString() to the end of the GString methods to make the output type the same as the other metrics, and make it a fairer test, StringBuilder and StringBuffer beat the GString methods for speed. However as GString can be used in place of String for most things (you just need to exercise caution with Map keys and SQL statements), it can mostly be left without this final conversion

添加这些测试(正如评论中所要求的那样)

Adding these tests (as it has been asked in the comments)

  'GString template toString' {
    "$foo$bar$baz".toString()
  }
  'Readable GString template toString' {
    "${foo}${bar}${baz}".toString()
  }

现在我们得到结果:

String adder                        514
GString template                    267
Readable GString template           269
GString template toString           478
Readable GString template toString  480
StringBuilder                       321
StringBuffer                        369

如你所见(正如我所说),它比 StringBuilder 或 StringBuffer 慢,但仍然比添加字符串快一点...

So as you can see (as I said), it is slower than StringBuilder or StringBuffer, but still a bit faster than adding Strings...

但仍然更具可读性.

更新到最新的 gbench,用于连接的更大字符串和使用初始化为合适大小的 StringBuilder 的测试:

Updated to latest gbench, larger strings for concatenation and a test with a StringBuilder initialised to a good size:

@Grab( 'org.gperfutils:gbench:0.4.2-groovy-2.1' )

def (foo,bar,baz) = [ 'foo' * 50, 'bar' * 50, 'baz' * 50 ]
benchmark {
  // Just add the strings
  'String adder' {
    foo + bar + baz
  }
  // Templating
  'GString template' {
    "$foo$bar$baz"
  }
  // I find this more readable
  'Readable GString template' {
    "${foo}${bar}${baz}"
  }
  'GString template toString' {
    "$foo$bar$baz".toString()
  }
  'Readable GString template toString' {
    "${foo}${bar}${baz}".toString()
  }
  // StringBuilder
  'StringBuilder' {
    new StringBuilder().append( foo )
                       .append( bar )
                       .append( baz )
                       .toString()
  }
  'StringBuffer' {
    new StringBuffer().append( foo )
                      .append( bar )
                      .append( baz )
                      .toString()
  }
  'StringBuffer with Allocation' {
    new StringBuffer( 512 ).append( foo )
                      .append( bar )
                      .append( baz )
                      .toString()
  }
}.prettyPrint()

给予

Environment
===========
* Groovy: 2.1.6
* JVM: Java HotSpot(TM) 64-Bit Server VM (23.21-b01, Oracle Corporation)
    * JRE: 1.7.0_21
    * Total Memory: 467.375 MB
    * Maximum Memory: 1077.375 MB
* OS: Mac OS X (10.8.4, x86_64)

Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On

                                    user  system  cpu  real

String adder                         630       0  630   647
GString template                      29       0   29    31
Readable GString template             32       0   32    33
GString template toString            429       0  429   443
Readable GString template toString   428       1  429   441
StringBuilder                        383       1  384   396
StringBuffer                         395       1  396   409
StringBuffer with Allocation         277       0  277   286

这篇关于使用 Groovy 进行字符串连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆