Reputation: 5206
What is the idiomatic way of working around this limitation of the null-safety in the Kotlin type system?
val strs1:List<String?> = listOf("hello", null, "world")
// ERROR: Type Inference Failed: Expected Type Mismatch:
// required: List<String>
// round: List<String?>
val strs2:List<String> = strs1.filter { it != null }
This question is not just about eliminating nulls, but also to make the type system recognize that the nulls are removed from the collection by the transformation.
I'd prefer not to loop, but I will if that's the best way to do it.
The following compiles, but I'm not sure it's the best way to do it:
fun <T> notNullList(list: List<T?>):List<T> {
val accumulator:MutableList<T> = mutableListOf()
for (element in list) {
if (element != null) {
accumulator.add(element)
}
}
return accumulator
}
val strs2:List<String> = notNullList(strs1)
Upvotes: 40
Views: 21473
Reputation: 3798
val strs1 = listOf("hello", null, "world") // [hello, null, world]
val strs2 = strs1.filter { !it.isNullOrBlank() } // [hello, world]
Upvotes: 0
Reputation: 2362
you can also use
mightContainsNullElementList.removeIf { it == null }
Upvotes: 2
Reputation: 6036
You can use filterNotNull
Here is a simple example:
val a: List<Int?> = listOf(1, 2, 3, null)
val b: List<Int> = a.filterNotNull()
But under the hood, stdlib does the same as you wrote
/**
* Appends all elements that are not `null` to the given [destination].
*/
public fun <C : MutableCollection<in T>, T : Any> Iterable<T?>.filterNotNullTo(destination: C): C {
for (element in this) if (element != null) destination.add(element)
return destination
}
Upvotes: 91