删除在groovy中用逗号分隔的字符串中的元素

时间:2018-05-07 23:08:37

标签: string groovy null remove-if

我正在以这种方式构建一个字符串:

def presentationType = "${feedDisplayType}, ${moduleType}, ${cellType}"

有时候变量有空值,结果字符串显示空值,我必须避免显示空值。

我想知道是否有某种方法可以在字符串中删除这些可能的空值,或者避免在它们出现时添加它。

我知道有可能并且更容易使用数组,但我想以更直接的方式使用字符串。

感谢您提前提供任何帮助。

2 个答案:

答案 0 :(得分:1)

有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中的所有条件语句,它的可读性要低得多。它也很容易出错 - 在这种情况下插入String时很容易出错。

连接列表方法是最慢的(大约比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

答案 1 :(得分:0)

修改:此答案已更改,因为无需为空条款打印“,”。

考虑:

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

请注意,在函数调用中,parens在Groovy中是可选的,因此${f x}等同于${f(x)}f在早期版本中最初是field,但为了简洁起见,我将其缩短了。