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

Equals与CompareTo契约不匹配引发TreeMap键查询异常排查

问题根因定位

你遇到的问题核心是违反了Java Sorted集合(TreeMap、TreeSet等)的强制契约:若a.compareTo(b) == 0,则必须满足a.equals(b) == true,反之亦然。你的Range类中compareTo方法和equals方法的逻辑完全不对齐,直接触发了TreeMap的判断异常。

代码逻辑逐点分析

  • equals方法实现符合契约:严格要求两个Range的first、last属性完全相等才返回true,逻辑无误。
  • hashCode方法实现符合契约:基于first、last计算哈希值,和equals逻辑完全对齐,无问题。
  • compareTo方法逻辑存在严重错误:
    你当前的实现逻辑仅在两个区间完全不重叠时才返回非0值:
    • 当前区间完全在参数区间左侧(last < 参数first)返回1
    • 当前区间完全在参数区间右侧(first > 参数last)返回-1
    • 其余所有场景(区间重叠、包含、交叉、边界重合)统一返回0
      这就导致大量equals返回false的Range对象,compareTo返回0,完全违背了Sorted集合的要求。

故障场景原因说明

TreeMap的所有键判断逻辑(containsKey、get、插入去重等)完全依赖Comparable的compareTo返回值,只要返回0就判定两个键相等,不会再调用equals做校验。因此只要你传入的Range和TreeMap中已存的任意Range存在重叠,就会被判定为键存在,自然就会出现“不存在的键校验也返回存在”的异常表现。

修复方案

如果你的需求是按区间自然排序,需将compareTo逻辑调整为和equals对齐,仅当两个Range的first、last都相等时才返回0:

@Override
public int compareTo(Range r) {
    // 优先比较区间起始值
    int firstCompare = this.first.compareTo(r.first);
    if (firstCompare != 0) {
        return firstCompare;
    }
    // 起始值相等时比较区间结束值
    return this.last.compareTo(r.last);
}

如果你的业务需要判断区间重叠,需要单独封装isOverlap(Range other)公共方法实现,不能将重叠判断逻辑写在compareTo中。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 05:18:05