有没有办法过滤掉null Any? Kotlin地图中的值?
我想通过应用一个函数来考虑一个允许Map<String, Any?>
对象作为Map<String,Any>
类型推断的函数。
我对Kotlin中的转换函数filterValues
filterNot
,并试图在地图上显示各种filter
和filterValues
filterNot
,如下所示:
val input = mapOf(Pair("first",null)) val filtered: Map<String,Any> = input.filter { it.value!=null }
它也没有与这些任何编译
input.filterValues { it!=null } input.filterNot { it.value==null } input.filterNot { it.value is Nothing }
我似乎得到最接近的是应用多个步骤或有一个未经检查的转换警告。 我会认为过滤值为!=null
就足够了。 我唯一的想法是,这是由于泛型?
过滤函数返回一个与原始地图具有相同通用类型的Map。 要转换值的类型,您需要映射值从任何? 到任何,通过演员。 编译器无法知道传递给filter()的谓词确保过滤映射的所有值都是非空的,因此它不能使用类型推断。 所以你最好的是使用
val filtered: Map<String, Any> = map.filterValues { it != null }.mapValues { it -> it.value as Any }
或者定义一个功能来完成一次过滤和转换,从而能够使用智能转换:
fun filterNotNullValues(map: Map<String, Any?>): Map<String, Any> { val result = LinkedHashMap<String, Any>() for ((key, value) in map) { if (value != null) result[key] = value } return result }
编译器不会深入地执行类型分析,例如, input.filterValues { it != null }
过滤掉映射中的null
值,因此结果映射应该具有非空值类型。 基本上,在类型和可空性方面可以有任意意义的任意谓词。
没有特殊的情况下,stdlib中的地图过滤null
值的功能(如iterables有.filterIsInstance<T>()
)。 因此,最简单的解决方案是应用一个未经检查的转换,从而告诉编译器,您确信没有违反类型安全:
@Suppress("UNCHECKED_CAST") fun <K, V> Map<K, V?>.filterNotNullValues() = filterValues { it != null } as Map<K, V>
另请参见: 另一个类似问题的问题 is
-check。