小编典典

Java TreeMap重复键

java

我想我可能已经发现Java错误。

我有一个TreeMap,其中使用了自定义比较器。但是,似乎当我将(key,value)放在已经存在的键上时,它不会覆盖该键,从而创建了重复的键。我想我已经验证了这一点,因为我尝试过

System.out.println(testMap.firstKey().equals(testMap.lastKey()));

这打印出真实的。有人知道为什么会这样吗?

这是比较器代码:

private class TestComp implements Comparator<String> {
    @Override
    public int compare(String s1, String s2){

        if (s1.equals(s2)) {
            return 0;
        }
        int temp = otherMap.get(s1).compareTo(otherMap.get(s2));
        if (temp > 0) {
            return 1;
        }
        return -1;

    }

阅读 676

收藏
2020-11-26

共1个答案

小编典典

比较器始终需要返回一致的结果,并且在TreeMap中使用时,应与equals保持一致。

在这种情况下,您的比较器违反了第一个约束,因为它不一定会给出一致的结果。

示例: 如果例如otherMap地图

"a" -> "someString"
"b" -> "someString"

那么这两个compare("a", "b")compare("b", "a")返回-1


请注意,如果您将实现更改为

if (s1.equals(s2)) {
    return 0;
}
return otherMap.get(s1).compareTo(otherMap.get(s2));

您违反了与equals保持一致的其他条件,因为即使不等于otherMap.get(s1).compareTo(otherMap.get(s2))也可能返回。0``s1``s2


从评论:

即使比较器的结果不一致,Java语言是否也不应该允许重复的键?

不,当您插入密钥时,TreeMap将使用比较器搜索数据结构以查看密钥是否已存在。如果比较器给出的结果不一致,则TreeMap可能 会在错误的位置查找
并得出该键不存在的结论,从而导致不确定的行为。

2020-11-26