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

为何HashMap调用toSortedMap后会少一个条目?

问题分析与解决:toSortedMap后丢失条目

你遇到的这个问题,核心原因是自定义的Comparator违反了SortedMap的比较契约,导致两个优先级相同的条目被错误判定为"相同键",进而被覆盖了。

为什么会丢失条目?

Kotlin的toSortedMap底层依赖Java的TreeMap,而TreeMap对比较器有严格的契约要求:如果compare(a, b) == 0,则必须满足a.equals(b) == true(等价一致性)。

看你的日志最后一次比较:对应test:xxx和test:yyy的两个UUID,它们的priority都是1,所以你的比较器返回了0。但这两个UUID是完全不同的(a.equals(b)为false),这就破坏了TreeMap的契约。此时TreeMap会认为这两个键是同一个,后面插入的xxx就会覆盖掉之前的yyy,最终导致排序后的Map少了一个条目。

修复方案

修改Comparator,当priority相同时,通过UUID本身的自然排序来区分不同的键,保证即使优先级相同,不同的UUID也会被视为独立的键。同时修正null处理的逻辑,避免破坏比较的对称性:

val sortedUuidToConfigMap = uuidToConfigMap.toSortedMap<UUID, Config>(object: Comparator<UUID>{
    override fun compare(o1: UUID?, o2: UUID?): Int {
        val config1 = uuidToConfigMap[o1]
        val config2 = uuidToConfigMap[o2]
        
        // 先处理null情况,用UUID自身的compareTo保证逻辑正确
        if (o1 == null) return o2?.let { -1 } ?: 0
        if (o2 == null) return 1
        
        if (config1 == null || config2 == null) {
            return o1.compareTo(o2)
        }
        
        // 优先按priority升序排序
        val priorityDiff = config1.priority - config2.priority
        if (priorityDiff != 0) {
            return priorityDiff
        }
        
        // priority相同时,按UUID排序,确保键的唯一性
        return o1.compareTo(o2)
    }
})

修复后效果

修改后,排序后的Map会保留全部4个条目:两个priority=1的条目都会存在,排序顺序是先按priority升序排列,priority相同的条目则按UUID的自然顺序排列。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:30:54