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

Kotlin实现HashMap扩容后测试失败,求排查resize函数问题

扩容后HashMap测试失败的resize函数问题排查

你的Kotlin HashMap实现在触发扩容后测试失败,核心问题集中在元素转移逻辑、计数同步以及配套函数的一致性上,以下是具体错误分析和修复方案:


1. added变量未同步实际元素数量

当原Map存在remove操作或重复put同一key时,added的数值会与实际非空元素数量不符。resize时你遍历的是map.filterNotNull()(真实存在的元素),但added仍保留原数值,这会导致后续扩容判断逻辑错误,甚至出现元素数量统计失效的情况。

修复方案:
在resize末尾同步added为新Map的实际元素数:

fun resize() {
    val newMap = arrayOfNulls<Entry>(map.size * 2)
    var newAddedCount = 0
    for (entry in map.filterNotNull()) {
        val index = hash(entry.key, newMap)
        val targetIndex = probe(index, entry.key, newMap)
        newMap[targetIndex] = Entry(entry.key, entry.value)
        newAddedCount++
    }
    map = newMap
    added = newAddedCount // 同步真实元素数量
}

2. put函数覆盖已有key时错误递增added

当前put逻辑中,即使覆盖已存在的key,仍会执行added++,导致added远大于实际元素数,提前触发扩容,甚至在resize后出现计数混乱。

修复方案:
仅当新增元素时才递增added:

fun put(key: Int, value: Int) {
    if (added.toDouble() / map.size >= LOAD_FACTOR) resize()
    val index = hash(key, map)
    val targetIndex = probe(index, key, map)
    if (map[targetIndex] == null) {
        added++
    }
    map[targetIndex] = Entry(key, value)
}

3. 哈希函数未处理负数key

Kotlin中负数取模结果为负数(如-1 % 1000 = -1),会导致数组越界异常。虽然你的测试用例可能使用正整数key,但这是潜在的致命bug。

修复方案:

fun hash(key: Int, m: Array<Entry?>) = (key % m.size + m.size) % m.size

4. (可选)统一探测逻辑的严谨性

当前probe函数逻辑与get函数对齐,但可以优化写法,避免冗余的取模操作:

fun probe(index: Int, key: Int, m: Array<Entry?>): Int {
    val size = m.size
    var localIndex = index % size
    while (true) {
        val currentEntry = m[localIndex]
        if (currentEntry == null || currentEntry.key == key) {
            return localIndex
        }
        localIndex = (localIndex + 1) % size
    }
}

修复后效果

以上修改解决了扩容过程中元素计数错误、哈希越界、重复key计数异常等问题,确保resize后所有元素能被正确转移,get/put/remove操作逻辑一致,测试用例在触发扩容后即可正常通过。

内容的提问来源于stack exchange,提问作者Dari V

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 22:05:54