在 groovy 中删除以逗号分隔的字符串中的元素
Remove elements in a string separated by commas in groovy
我正在以这种方式构建字符串:
def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"
发生的情况是有时变量有空值,而结果字符串显示此空值,我必须避免显示空值。
我想知道是否有某种方法可以删除字符串中可能存在的空值或避免在它们出现时添加此值。
我知道用数组来做是可能的而且更容易,但我想以更直接的方式用字符串来做。
提前感谢您的帮助。
编辑:此答案已更改,因为要求不为空术语打印“,”。
考虑:
def feedDisplayType = 'abc'
def moduleType = null
def cellType = 'ijk'
def f = { s, isLast = false ->
def token = s ?: ''
def seperator = (!s || isLast) ? '' : ','
"${token}${seperator}"
}
def presentationType = "${f feedDisplayType}${f moduleType}${f cellType,true}"
assert 'abc,ijk' == presentationType
请注意,在函数调用中,括号在 Groovy 中是可选的,因此 ${f x}
等同于 ${f(x)}
。 f
在早期版本中最初是 field
,但为了简洁起见,我将其缩短。
有3个选项:
1。 GString 插值
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
2。使用 StringBuilder
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
3。以 ,
作为分隔符加入列表
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
基准
在得出结论之前,让我们使用 GBench 工具对所有 3 种方法进行基准测试:
@Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')
def feedDisplayType = 'test'
def moduleType = null
def cellType = ''
def r = benchmark {
'GString method' {
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
}
'StringBuilder method' {
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
}
'Join list method' {
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
}
}
r.prettyPrint()
输出
Environment
===========
* Groovy: 2.4.12
* JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
* JRE: 1.8.0_171
* Total Memory: 236 MB
* Maximum Memory: 3497 MB
* OS: Linux (4.16.5-200.fc27.x86_64, amd64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
GString method 265 2 267 268
StringBuilder method 72 4 76 77
Join list method 484 3 487 495
结论
如果您的目标是最高吞吐量,StringBuilder
方法是最好的方法(平均时间为 77 纳秒)。
GString
方法比 StringBuilder
慢几倍,并且由于单个 GString 中的所有条件语句,它的可读性要差得多。它也很容易出错——在这种情况下插入字符串时很容易出错。
joining list方法是最慢的(只比GString方法慢2倍左右),但是是最干净的。而且它仍然非常快——在大多数情况下 495 纳秒是可以接受的。当然优化取决于具体的用例——如果你必须每秒执行这部分代码一百万次,那么使用 StringBuilder
更有意义。
基准极端案例
为了使这个例子完整,我们也来看看基准测试中的极端情况。我们使用不同输入的相同代码。
输入:
def feedDisplayType = 'lorem ipsum'
def moduleType = 'dolor sit amet'
def cellType = '123456789'
输出:
user system cpu real
GString method 387 1 388 390
StringBuilder method 170 0 170 175
Join list method 847 6 853 859
输入:
def feedDisplayType = ''
def moduleType = ''
def cellType = ''
输出:
user system cpu real
GString method 237 5 242 242
StringBuilder method 44 0 44 44
Join list method 441 0 441 446
我正在以这种方式构建字符串:
def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"
发生的情况是有时变量有空值,而结果字符串显示此空值,我必须避免显示空值。
我想知道是否有某种方法可以删除字符串中可能存在的空值或避免在它们出现时添加此值。
我知道用数组来做是可能的而且更容易,但我想以更直接的方式用字符串来做。
提前感谢您的帮助。
编辑:此答案已更改,因为要求不为空术语打印“,”。
考虑:
def feedDisplayType = 'abc'
def moduleType = null
def cellType = 'ijk'
def f = { s, isLast = false ->
def token = s ?: ''
def seperator = (!s || isLast) ? '' : ','
"${token}${seperator}"
}
def presentationType = "${f feedDisplayType}${f moduleType}${f cellType,true}"
assert 'abc,ijk' == presentationType
请注意,在函数调用中,括号在 Groovy 中是可选的,因此 ${f x}
等同于 ${f(x)}
。 f
在早期版本中最初是 field
,但为了简洁起见,我将其缩短。
有3个选项:
1。 GString 插值
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
2。使用 StringBuilder
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
3。以 ,
作为分隔符加入列表
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
基准
在得出结论之前,让我们使用 GBench 工具对所有 3 种方法进行基准测试:
@Grab(group='org.gperfutils', module='gbench', version='0.4.3-groovy-2.4')
def feedDisplayType = 'test'
def moduleType = null
def cellType = ''
def r = benchmark {
'GString method' {
def presentationType = "${feedDisplayType != null && !feedDisplayType.isEmpty() ? feedDisplayType + ', ' : ''}${moduleType != null && !moduleType.isEmpty() ? moduleType + ', ' : ''}${cellType != null && !cellType.isEmpty() ? cellType : ''}".toString()
}
'StringBuilder method' {
def sb = new StringBuilder()
if (feedDisplayType != null && !feedDisplayType.isEmpty()) {
sb.append(feedDisplayType)
sb.append(', ')
}
if (moduleType != null && !moduleType.isEmpty()) {
sb.append(moduleType)
sb.append(', ')
}
if (cellType != null && !cellType.isEmpty()) {
sb.append(cellType)
}
def presentationType = sb.toString()
}
'Join list method' {
def presentationType = [feedDisplayType, moduleType, cellType].findAll { str -> str != null && !str.isEmpty() }.join(', ')
}
}
r.prettyPrint()
输出
Environment
===========
* Groovy: 2.4.12
* JVM: OpenJDK 64-Bit Server VM (25.171-b10, Oracle Corporation)
* JRE: 1.8.0_171
* Total Memory: 236 MB
* Maximum Memory: 3497 MB
* OS: Linux (4.16.5-200.fc27.x86_64, amd64)
Options
=======
* Warm Up: Auto (- 60 sec)
* CPU Time Measurement: On
user system cpu real
GString method 265 2 267 268
StringBuilder method 72 4 76 77
Join list method 484 3 487 495
结论
如果您的目标是最高吞吐量,StringBuilder
方法是最好的方法(平均时间为 77 纳秒)。
GString
方法比 StringBuilder
慢几倍,并且由于单个 GString 中的所有条件语句,它的可读性要差得多。它也很容易出错——在这种情况下插入字符串时很容易出错。
joining list方法是最慢的(只比GString方法慢2倍左右),但是是最干净的。而且它仍然非常快——在大多数情况下 495 纳秒是可以接受的。当然优化取决于具体的用例——如果你必须每秒执行这部分代码一百万次,那么使用 StringBuilder
更有意义。
基准极端案例
为了使这个例子完整,我们也来看看基准测试中的极端情况。我们使用不同输入的相同代码。
输入:
def feedDisplayType = 'lorem ipsum'
def moduleType = 'dolor sit amet'
def cellType = '123456789'
输出:
user system cpu real
GString method 387 1 388 390
StringBuilder method 170 0 170 175
Join list method 847 6 853 859
输入:
def feedDisplayType = ''
def moduleType = ''
def cellType = ''
输出:
user system cpu real
GString method 237 5 242 242
StringBuilder method 44 0 44 44
Join list method 441 0 441 446