Reputation: 6949
I am new to Kotlin, and I am looking for help in rewriting the following code to be more elegant.
var s: String? = "abc"
if (s != null && s.isNotEmpty()) {
// Do something
}
If I use the following code:
if (s?.isNotEmpty()) {
The compiler will complain that
Required: Boolean
Found: Boolean?
Thanks.
Upvotes: 43
Views: 31189
Reputation: 5093
Another extension option. I was looking for a way of validating a bunch of strings and then using them, and the nested blocks are a pain for reading in that aspect.
fun String?.notNullOrEmpty(illegalArgumentExceptionMsg: String): String {
return if (this == null || this.isEmpty()) throw IllegalArgumentException(illegalArgumentExceptionMsg) else this
}
simple use
val myNullOrEmptyString: String? = "bar"
val myNotNullString = myNullOrEmptyString.notNullOrEmpty("myNullOrEmptyString should not be empty")
use
val myNullOrEmptyString: String? = "bar"
val myNotNullString: String = myNullOrEmptyString.notNullOrEmpty("myNullOrEmptyString should not be empty")
Test or uses
@Test
fun emptyNotNullExtension() {
val msg = "foo"
assertThatThrownBy {
val emptyNotNullString: String = "".notNullOrEmpty(msg)
}
.isExactlyInstanceOf(IllegalArgumentException::class.java)
.hasMessageContaining(msg)
assertThatThrownBy {
val emptyNotNullString: String = null.notNullOrEmpty(msg)
}
.isExactlyInstanceOf(IllegalArgumentException::class.java)
.hasMessageContaining(msg)
val myNullOrEmptyString: String? = "bar"
val myNotNullString: String = myNullOrEmptyString.notNullOrEmpty("myNullOrEmptyString should not be empty")
}
Upvotes: 0
Reputation: 869
Or you can create an Extension Function:
public inline fun String?.ifNotEmpty(crossinline block: (String) -> Unit): Unit {
if (this != null && this.isNotEmpty()) {
block(this)
}
}
I find this approach more readable in context of Jetpack Compose
which is a UI Toolkit.
handles.twitter.ifNotEmpty {
SocialMediaItem(handle = it, type = SocialMedia.TWITTER)
}
In this case the intention is to only display that block of UI if Twitter handle is not null, and is not an empty string.
Upvotes: 3
Reputation: 41678
You can use isNullOrEmpty
or its friend isNullOrBlank
like so:
if(!s.isNullOrEmpty()){
// s is not empty
}
Both isNullOrEmpty
and isNullOrBlank
are extension methods on CharSequence?
thus you can use them safely with null
. Alternatively turn null
into false like so:
if(s?.isNotEmpty() ?: false){
// s is not empty
}
you can also do the following
if(s?.isNotEmpty() == true){
// s is not empty
}
Upvotes: 60
Reputation: 1072
or create an extension method and use it as a safe call:
fun String?.emptyToNull(): String? {
return if (this == null || this.isEmpty()) null else this
}
fun main(args: Array<String>) {
val str1:String?=""
val str2:String?=null
val str3:String?="not empty & not null"
println(str1.emptyToNull()?:"empty string")
println(str2.emptyToNull()?:"null string")
println(str3.emptyToNull()?:"will not print")
}
Upvotes: 2
Reputation: 19998
Although I like the answer by @miensol very much, my answer would be (and that is why I do not put it in a comment): if (s != null && s.isNotEmpty()) { … }
actually is the idiomatic way in Kotlin. Only this way will you get a smart cast to String
inside the block, while with the way in the accepted answer you will have to use s!!
inside the block.
Upvotes: 6