You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:53:24