【问题标题】:Why is is my TreeMap not sorted correctly?为什么我的 TreeMap 没有正确排序?
【发布时间】:2017-04-12 06:48:41
【问题描述】:
import java.util.TreeMap;

class Point implements Comparable<Point>{
    private int x, y;
    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object arg0) {
        Point p = (Point) arg0;
        return (this.x == p.x && this.y == p.y);
    }

    @Override
    public String toString() {
        return "("+x+", "+y+")";
    }

    @Override
    public int compareTo(Point arg0) {
        if(this.x == arg0.x && this.y == arg0.y)
            return 0;
        return -1;
    }

}

public class Test {
    static int row, col;
    static TreeMap<Point, Integer> dist;
    public static void main(String[] args) {
        dist = new TreeMap<>();
        row = 4;
        col = 7;
        for(int i=0; i<row; i++){
            for(int j=0; j<col; j++){
                Point p = new Point(i, j);
                dist.put(p, Integer.MAX_VALUE);
            }
            if(i >= 1)
                System.out.println(i+": "+dist.keySet().contains(new Point(1, 5)));
        }
    }
}

输出应该是: 1:真 2:真 3:是的

但它来了 1:真 2:错误 3:错误

有人能解释一下为什么会出现这个输出吗? 如果我采用预定义的数据类型,此代码工作正常 作为地图的关键。 有人可以解释一下为什么会出现这个输出吗? 如果我采用预定义的数据类型,此代码工作正常

作为地图的关键。

【问题讨论】:

  • 你尝试调试了吗?
  • 您的比较方法总是返回 0 或 -1。这是否符合 Comparable.compare 文档中的预期?
  • 应该返回所有 3 个值 1,0,-1 吗?
  • @Prince 是的,没错。

标签: java treemap


【解决方案1】:

您的 compareTo 不是 transitive 反对称的。详情请参阅here

@Override
public int compareTo(Point arg0) {
    if(this.x == arg0.x && this.y == arg0.y)
        return 0;
    return -1;
}

a!=ba.compareTo(b) 返回 -1,但 b.compareTo(a) 也返回 -1。这会导致排序错误。

【讨论】:

    【解决方案2】:

    正如@RobAu 指出的那样,问题在于您的compareTo 方法。请注意该方法的文档:

    返回负整数、零或正整数作为此对象 小于、等于或大于指定对象。

    您需要修改代码以允许在点之间进行正确比较,也就是说,您必须为点提出一些排序。例如,这是一个可行的替代实现:

    @Override
    public int compareTo(Point arg0) {
        int ret = Integer.compare(x, arg0.x);
        if (ret == 0) {
            ret = Integer.compare(y, arg0.y);
        }
        return ret;
    }
    

    【讨论】:

    • @Prince 不用担心——但我认为给用户RobAu 信用会更公平,他的回答是正确的(在我之前)我只是添加了引用和代码示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2021-12-31
    • 1970-01-01
    相关资源
    最近更新 更多