如何在Kotlin中安全地将原始Map转换为Map<String, List<Int>>?
解决方案
你可以基于已实现的checkItemsAre函数,编写一个专门的Map转换函数,安全地将Map<*, *>转换为Map<String, List<Int>>,完全替代不安全的as关键字。
1. 实现安全转换函数
直接编写目标明确的扩展函数,逐个验证Map的键和值:
// 你已实现的List元素验证函数 inline fun <reified T : Any> List<*>.checkItemsAre(): List<T> { return this.filterIsInstance<T>().takeIf { it.size == this.size } ?: throw IllegalArgumentException("列表中存在非${T::class.simpleName}类型的元素") } // 新增的Map安全转换函数 fun Map<*, *>.toSafeStringIntListMap(): Map<String, List<Int>> { return buildMap { this@toSafeStringIntListMap.forEach { (key, value) -> // 验证键为String类型 val stringKey = key as? String ?: throw IllegalArgumentException("键 '$key' 不是String类型") // 验证值为List且所有元素都是Int val intList = when (value) { is List<*> -> value.checkItemsAre<Int>() else -> throw IllegalArgumentException("键 '$stringKey' 对应的值不是List类型") } put(stringKey, intList) } } }
2. 用法示例
fun main() { // 合法的原始Map val validRawMap: Map<*, *> = mapOf( "group1" to listOf(1, 3, 5), "group2" to listOf(2, 4, 6) ) val safeMap = validRawMap.toSafeStringIntListMap() println(safeMap) // 输出: {group1=[1, 3, 5], group2=[2, 4, 6]} // 包含非法数据的Map val invalidRawMap: Map<*, *> = mapOf( 100 to listOf(1, 2), // 键为Int而非String "group3" to listOf("a", 3) // 列表包含非Int元素 ) try { invalidRawMap.toSafeStringIntListMap() } catch (e: IllegalArgumentException) { println(e.message) // 会抛出对应错误信息,比如"键 '100' 不是String类型" } }
3. 方案优势
- 彻底消除
as关键字的不安全转换风险,不会在运行时静默忽略类型不匹配问题 - 提供明确的错误提示,无论是键类型错误、值非List,还是列表元素非Int,都能抛出指向具体问题的异常
- 复用你已实现的
checkItemsAre函数,保证列表元素的类型验证逻辑一致
内容的提问来源于stack exchange,提问作者gstackoverflow
相关产品推荐
相关产品推荐

