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

Java TreeMap无法获取已存在的Coordenada键问题求助

问题根源:Coordenada类的compareTo方法实现错误

你遇到的问题核心在于Coordenada类的compareTo方法逻辑不正确,导致TreeMap无法正确识别已插入的键。TreeMap是基于红黑树实现的有序集合,它完全依赖compareTo方法的结果来判断键的相等性和排序——当compareTo返回0时,TreeMap认为两个键是同一个;而你的equals方法逻辑和compareTo不一致,且compareTo本身的比较逻辑存在错误。

分析compareTo的错误逻辑

你的compareTo方法现在的判断顺序是:

  1. 如果当前x坐标大于目标x,返回1
  2. 如果当前y坐标大于目标y,返回1
  3. 如果当前x坐标小于目标x,返回-1
  4. 如果当前y坐标小于目标y,返回-1
  5. 否则返回0

这个逻辑会导致完全错误的比较结果,比如:

  • 比较Coordenada(12,2)和Coordenada(13,1)时,你的方法会因为2>1直接返回1,认为(12,2)比(13,1)大,但实际上前者的x坐标更小,应该是更小的键。
  • 这种错误的排序逻辑会让TreeMap在插入和查找时,把键放到错误的树节点位置,导致你明明看到键已插入,却用get方法找不到它。

修复方案

1. 修正compareTo方法

正确的比较逻辑应该是先比较x坐标,x相等时再比较y坐标,这样才能保证排序的一致性,同时和equals方法的逻辑匹配。修改后的代码如下:

@Override
public int compareTo(Coordenada o) {
    // 先比较x坐标,x不同直接返回比较结果
    int xComparison = Integer.compare(this.coordenada[0], o.coordenada[0]);
    if (xComparison != 0) {
        return xComparison;
    }
    // x坐标相等时,再比较y坐标
    return Integer.compare(this.coordenada[1], o.coordenada[1]);
}

2. 补充重写hashCode方法

虽然TreeMap不依赖hashCode,但根据Java的约定,重写equals必须同时重写hashCode,否则如果这个类以后被用到HashMap、HashSet等基于哈希的集合中,会出现不可预期的问题。添加如下实现:

@Override
public int hashCode() {
    return Objects.hash(coordenada[0], coordenada[1]);
}

为什么之前的代码会出现问题?

当你调用map.putIfAbsent(c, new TreeMap<>())插入Coordenada(12,2)时,TreeMap通过错误的compareTo逻辑将它放到了某个位置;之后调用map.get(helper_co)时,helper_co虽然和插入的键equals返回true,但compareTo的结果不为0,TreeMap会认为这是两个不同的键,因此返回null。

修正compareTo后,TreeMap的排序和键判断逻辑会和equals保持一致,就能正常找到已插入的键了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:28:38