Решение
fun <K, V> Map<out K?, V?>.filterNotNull(): Map<K, V> = this.mapNotNull {
it.key?.let { key ->
it.value?.let { value ->
key to value
}
}
}.toMap()
мне кажется слишком сложным. Это может быть записано как
fun <K, V> Map<out K?, V?>.filterNotNull(): Map<K, V> =
filter { it.key != null && it.value != null } as Map<K, V>
Уродливое приведение необходимо, так как компилятор не может (пока) сделать вывод, что ни ключи, ни значения не содержат ноль.
Словопредупреждение, касающееся ковариации out K?
Да, он дает возможность использовать один и тот же метод не только для Map<String?, Stuff?>
, но и для Map<String, Stuff?>
(ключ может обнуляться или нет). Но эта свобода имеет свою цену. Для карт, которые, как известно, не имеют нулевых ключей, вам не нужно платить нулевое сравнение для каждой записи.
В вашем первоначальном решении - что без ковариации на K - компилятор может помешать вам вызвать этот неэффективный метод. Правильный метод тогда, вероятно, будет
fun <K, V> Map<K, V?>.filterValuesNotNull() = filterValues { it != null } as Map<K, V>