java map键值重复,Java TreeMap重复键

I think I may have found a bug in Java.

I have a TreeMap in which I use a custom comparator. However, it seems when I put(key, value), on a key that already exists, it does not override the key, thus creating duplicate keys. I think I have verified this because I tried:

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

And this prints out true. Anyone know why this is happening?

This is the comparator code:

private class TestComp implements Comparator {

@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;

}

解决方案

A comparator always needs to return consistent results, and when used in a TreeMap, be consistent with equals.

In this case your comparator violates the first constraint since it does not necessarily give consistent results.

Example: If for instance otherMap maps

"a" -> "someString"

"b" -> "someString"

then both compare("a", "b") and compare("b", "a") will return -1.

Note that if you change the implementation to

if (s1.equals(s2)) {

return 0;

}

return otherMap.get(s1).compareTo(otherMap.get(s2));

you break the other criteria of being consistent with equals, since otherMap.get(s1).compareTo(otherMap.get(s2)) might return 0 even though s1 does not equal s2.

I've elaborated on this in a self-answered follow up question here.

From the comments:

Even if a comparator gives inconsistent results, shouldn't the Java language still not allow duplicate keys?

No, when you insert a key, the TreeMap will use the comparator to search the data structure to see if the key already exists. If the comparator gives inconsistent results, the TreeMap might look in the wrong place and conclude that the key does not exist, leading to undefined behavior.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值