【问题标题】:Java TreeMap not sorted according to passed comparatorJava TreeMap 未根据传递的比较器排序
【发布时间】:2022-01-19 15:42:12
【问题描述】:

我已经实现了一个包含蓝图的 TreeMap(为了简化它)。

private TreeMap<BuildingFloorKey, Blueprint> blueprints = new TreeMap<>((o1, o2) -> {
        int value = o1.compareTo(o2);
        return value;
});

为了使用 building(在我的例子中称为 complex)和 floor 作为元组键,我编写了以下类:

public static class BuildingFloorKey {
    private Complex mComplex;
    private int mFloor;

    public BuildingFloorKey(Complex complex, int floor){
        mComplex = complex;
        mFloor = floor;
    }

    @Override
    public boolean equals(Object other) {
        if (!(other instanceof BuildingFloorKey)) return false;
        BuildingFloorKey that = (BuildingFloorKey) other;
        return mFloor == that.mFloor && mComplex.equals(that.mComplex);
    }

    @Override
    public int hashCode() {
        return Arrays.hashCode(new Object[]{mComplex, mFloor});
    }

    public int compareTo(BuildingFloorKey otherKey){
        if(this.equals(otherKey)) return 0;

        //same complex -> compare floors
        else if (this.getComplex().equals(otherKey.getComplex())){
            return otherKey.getFloorInt() - this.getFloorInt();
        }
        //different complexes (incl. some modification for special cases)
        else return -(Math.abs(otherKey.mFloor + 2) + 100);
    }
}

我正在开发一个 Android 应用程序,我想通过按钮点击蓝图。为此,我使用了 TreeMap.lowerKey(otherKey) 和 TreeMap.higherKey(otherKey) 方法。像这样:

@Override
    public void onNextPlanClicked() {
           nextFloorPlan = blueprints.higherKey(currentlyDisplayedPlan);
           drawFloorPlan(nextFloorPlan);
        }

例如,我有一个用例,其中一组蓝图是

  • 04|02
  • 03|03
  • 04|-1
  • 03|00

(格式:复杂|楼层)。不幸的是,它在 TreeMap 中没有正确排序(如您所见 - 上面的列表与调试器中 TreeMap 的条目一样排序)。

我阅读了一些关于 TreeMap Sorting using case-sensitive Strings 的文章。但我实际上使用的是整数。所以我不明白为什么排序和使用 lowerKey() 和 highKey() 不能正常工作。我搞砸了比较器吗?有人可以帮忙吗?

【问题讨论】:

  • 通过更改为 LinkedHashMap 解决了这个问题(我认识到我添加条目的顺序是我想要的)。谢谢!

标签: java android comparator treemap


【解决方案1】:

我认为您的问题非常简单,您的 compareTo 方法应该有一个覆盖。您需要将实现 Comparable 添加到您的 BuildingFloorKey 定义中,然后它将您的 compareTo 参数作为 TreeMap 可以识别的可比较参数。

【讨论】:

  • 谢谢,这是一个很好的完整性提示。解决了一些疯狂的按钮行为,但不幸的是,蓝图的顺序仍然不正确。
  • 对不起,我可能应该发表评论而不是回答。查看您的 compareTo 方法,第三个等式已关闭。它本质上说返回负数。这就是它所说的,对于 compareTo,我们只关心 +/-/0。所以排序会弄得一团糟,因为如果它们是不同的复合体,无论哪个是“其他”复合体,总是会注册为更高的。
  • 好的,谢谢。确实我也有这个想法,然后就忘记了。所以 compareTo 只返回“更小”、“更大”和“相等”的结果,我现在是吗?
  • 这纠正了行为!虽然我认识到项目中的一些细节和用例让我改变了一切;)但非常感谢!
猜你喜欢
  • 1970-01-01
  • 2012-04-24
  • 2010-12-19
  • 1970-01-01
  • 2011-12-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
相关资源
最近更新 更多