如何摆脱;空";当在groovy中浓缩字符串时?

如何摆脱;空";当在groovy中浓缩字符串时?,groovy,Groovy,我有一节课 class A{ String name String address } def a = new A() a.address = "some address" println "${a.name} ${a.address}" => "null some address" 此处a.name为空,因此打印的字符串将包含“null”,但我希望结果是忽略空值的“某个地址” 我知道我可以在打印时使用println“${a.name:”“}${a.addre

我有一节课

class A{
    String name
    String address
}

def a = new A()
a.address = "some address"    
println "${a.name} ${a.address}"  => "null some address"
此处
a.name
为空,因此打印的字符串将包含“null”,但我希望结果是
忽略空值的“某个地址”


我知道我可以在打印时使用
println“${a.name:”“}${a.address:”“}”
有什么更简单的解决方案吗?

您可以在类中实现
toString
方法,如下所示:

class A{
  String name
  String address
  String toString() {
    "${name ?: ''} ${address ?: ''}".trim()
  }
}
那就做吧

def a = new A( address:'some address' )
println a
要打印出
一些地址
,但这仍然使用了您在问题中使用的Elvis运算符


不确定你能做的更简单…

不确定是否更简单,但是:

[a.name, a.address].findAll().join(' ')
你当然可以把它和Tim的toString结合起来

请注意,如果任何值可能是“falsy”(例如0),它将过滤掉它。您可以通过以下方式解决此问题:

[a.name, a.address].findAll {it != null}.join(' ')

您可以为Groovy的
null
对象重新定义
toString
方法,以返回空字符串,而不是
null

def a = [a:null, b:'foobar']
println "${a.a} ${a.b}"
org.codehaus.groovy.runtime.NullObject.metaClass.toString = {return ''}
println "${a.a} ${a.b}"
这将打印:

null foobar
 foobar
如果您只想临时重新定义
toString
,请在上次
打印…
后添加以下内容以将其更改回去:

org.codehaus.groovy.runtime.NullObject.metaClass.toString = {return 'null'}

您还可以使用Groovy
类别
null
更改为字符串
行为。例如:

@Category(org.codehaus.groovy.runtime.NullObject) class MyNullObjectCategory {def toString() {''}}
use (MyNullObjectCategory) {
    println "${a.a} ${a.b}"
}

@donnior它比纯java做的同样的事情好很多。。。我能想到的最小值是:
String.format(“%s%s”,name==null?”):name,address==null?”:address.trim()
;-)基于您的答案,您还可以临时使用一个类别来重新定义它:
@category(NullObject)class NullObjectCategory{String toString(){'}}
,然后
在任何您想要消除空值的地方使用它:
使用(NullObjectCategory){assert“$a.a$a.b”=='foobar'}
谢谢,这将解决我的问题,我认为没有人希望在向用户打印字符串时得到“null”webpages@JustinPiper说得好!谢谢你的额外投入。更新答案。@donnior很乐意帮忙。不要忘记接受最能解决你问题的答案;有关更多信息,请参阅。接受您问题的答案可确保SO社区在未来更愿意帮助您。只有一个问题:在提出此解决方案时,您是否考虑过线程安全?特别是@JustinPiper提出的解决方案可能是线程安全的,我不知道use(Category)技术是否绑定到当前线程,但我认为最初的解决方案有点危险,如果您只想去掉网页上的“null”。例如,在系统日志中区分null和“”很重要。对于映射[1:false,2:true,3:null]。findAll{it.value!=null}