记录个Java/Groovy的小问题:空字符串调用split函数返回非空数组

问题复现

最近写了一个groovy替换程序增量流水线脚本(会Java也能看懂),示意脚本如下:

groovy 复制代码
//获取文件列表方法
def listFiles(folder) {
    def output = sh(script: "ls ${folder}", returnStdout: true).trim()
    return output.split('\n') as List
}
//调用以上方法获取lib目录下的需添加的jar列表
def addJars = listFiles("lib")
println "addJars值为"+addJars 
//List判空
if(addJars != null && !addJars.isEmpty()){
  println "addJars列表长度="+addJars.size()
  for(addJar in addJars){
    println "addJar="+addJar
  }
}

最终输出结果:

bash 复制代码
addJars值为[]
addJars列表长度=1
addJar=

哎?我的判空没生效么?!

分析

ls 目录返回的字符串一般是\n文件1\n文件2\n这种格式的字符串,用\n分隔应该是没问题的。

继续分析output.split('\n') as List 这行,经过测试可以发现个现象:当output字符串为空字符串""时,这个split方法转换的数组/列表是带有一个空字符串元素的!

可简化此处代码进行测试:

这个split方法是groovy继承java的String类型的方法,用Java写代码也有这个问题:

所以说,split方法当字符串为空字符串时会返回带有空字符串元素的数组!

解决

  • 方案1:split后判断数组长度为1,且首个元素为空字符串时,返回一个空数组/列表。
  • 方案2:split返回的数组去除空字符串元素。

我的解法采用了方案2,同时用上了groovy的运算符重载:

groovy 复制代码
def listFiles(folder) {
    def output = sh(script: "ls ${folder}", returnStdout: true).trim()
    def list = output.split('\n') as List
    return list - ''
}