I'm calling a third-party function (which I can't change) which returns a list of nullable elements (List<Int?>
), but I know for certain that all elements are non-null. I then want to pass this list to another third-party function, which takes a list of non-null elements (List<Int>
). If I cast it, as I do in the code below, I get a warning. If I use filterNotNull
it copies the list unnecessarily. How can I avoid copying the list and also not triggering an unchecked cast warning?
fun foo() {
val a = bar(includeNullElements = false)
baz(a.map { it!! }) // Undesirable to copy large list
baz(a.filterNotNull()) // Undesirable to copy large list
baz(a as List<Int>) // Gives unchecked cast warning
}
/**
* This function comes from a library that I can't change.
* Returns a very large list of elements known to be non-null,
* but unfortunately are typed as nullable.
*/
fun bar(includeNullElements: Boolean): List<Int?> = TODO()
/**
* This function comes from a library that I can't change.
* Takes a list of non-null elements.
*/
fun baz(a: List<Int>) {
println(a)
}
What you can do if you absolutely don't want to copy the list, is that you cast the list to a non-nullable list, you suppress the warning for an unchecked cast, but you don't do that in an unsafe way, because you check the list before casting:
fun <T: Any> List<T?>.asNonNullable(): List<T> {
if(any { it == null }) throw IllegalArgumentException("unexpected null element")
@Suppress("UNCHECKED_CAST")
return this as List<T>
}