Kotlin报错No set method providing array access,无法修改Map值求助
问题分析与解决
核心问题
你代码里的resourceAllocation是MutableList<Map<String, Any>>,但Map是只读不可变的——哪怕你把它放进可变列表里,单个Map实例本身还是不能修改键值对的。这就是你没法给resource["usage"]赋值的根本原因。
修正方案
只需要把列表元素的类型换成MutableMap,同时创建新资源时用可变Map:
fun lastFinishMetric(currentSchedulePlan: List<Map<String, Any>>): Triple<Int, Int, Double> { var constraintResource = 0 // 修改1:把列表元素类型改为MutableMap val resourceAllocation = mutableListOf<MutableMap<String, Any>>() var latestFinish = 0 for (task in currentSchedulePlan) { val taskFinish = task["finish"] as Int val taskResource = task["resource"] as Int val taskDuration = task["duration"] as Int if (taskFinish > latestFinish) { latestFinish = taskFinish } // 修改2:用find简化资源查找,代替手动循环 val existingResource = resourceAllocation.find { it["resource"] == taskResource } if (existingResource != null) { val currentUsage = existingResource["usage"] as Int existingResource["usage"] = currentUsage + taskDuration } else { // 修改3:用mutableMapOf创建可变Map resourceAllocation.add(mutableMapOf("resource" to taskResource, "usage" to taskDuration)) } } // 处理空列表的情况,避免NullPointerException val constraint = resourceAllocation.maxByOrNull { it["usage"] as Int } ?: return Triple(0, 0, 0.0) constraintResource = constraint["resource"] as Int val constraintUsage = constraint["usage"] as Int val occupationRate = constraintUsage.toDouble() / latestFinish.toDouble() return Triple(latestFinish, constraintResource, occupationRate) }
额外优化建议
用Map<String, Any>这种无类型约束的集合很容易出现类型转换错误,更符合Kotlin风格的做法是定义数据类:
data class Task(val finish: Int, val resource: Int, val duration: Int) data class ResourceAllocation(var resource: Int, var usage: Int) fun lastFinishMetric(currentSchedulePlan: List<Task>): Triple<Int, Int, Double> { var constraintResource = 0 val resourceAllocation = mutableListOf<ResourceAllocation>() var latestFinish = 0 for (task in currentSchedulePlan) { if (task.finish > latestFinish) { latestFinish = task.finish } val existingResource = resourceAllocation.find { it.resource == task.resource } if (existingResource != null) { existingResource.usage += task.duration } else { resourceAllocation.add(ResourceAllocation(task.resource, task.duration)) } } val constraint = resourceAllocation.maxByOrNull { it.usage } ?: return Triple(0, 0, 0.0) constraintResource = constraint.resource val constraintUsage = constraint.usage val occupationRate = constraintUsage.toDouble() / latestFinish.toDouble() return Triple(latestFinish, constraintResource, occupationRate) }
这样完全避免了类型转换的风险,代码可读性和安全性都更高。
内容的提问来源于stack exchange,提问作者MbeezyP
相关产品推荐
相关产品推荐

