5

为什么可以循环keySetTreeMap 并获得一个.containsKey == false

for (Object thisObject : map.keySet()) {
    if (!map.containsKey(thisObject)) {
        System.out.println("This line should be never reached.");
    }
}

经过很多,很多不同的迭代和调用这条线被击中。Amap.get(thisObject)会返回null。但调试显示键(相同的引用、值和哈希)和实际值在映射中。地图很小(25 个元素)TreeMap<Long, Double>

更新:

正如@rgettman猜测的那样,在构造 TreeMap 时使用了一种自定义排序Comparator(没有看到它,因为它是从另一个类构造的)。这个比较器只是(我猜)从这里复制粘贴

改变Comparator

  public int compare(Object a, Object b) {

    if((Double)base.get(a) > (Double)base.get(b)) {
      return 1;
    } else if((Double)base.get(a) == (Double)base.get(b)) {
      return 0;
    } else {
      return -1;
    }
  }

...
    } else if(base.get(a).equals(base.get(b))) {
      return 0;
...

解决问题。这个问题在数百万次操作之后出现的原因是,没有任何情况下映射具有两个不同键的两个相似值,因为这在上下文中是非常不可能的。

所以在:

25151l, 1.7583805400614032
24827l, 1.7583805400614032

它失败。

谢谢你的帮助!

4

3 回答 3

0

这些实现类中的大多数都依赖于支持和正确的 hashCode() 和 equals()。

如果您确实具有来自对象的相同哈希码,请尝试匹配相等。我建议的答案是它们不匹配。

否则,场景应该足够小,您可以发布对象和/或它们各自的哈希码和 equals 方法。

于 2013-08-08T06:16:13.530 回答
0

我刚刚执行了代码,这个案例对我来说确实返回了 true

          TreeMap<Long,Double> otm = new TreeMap<Long, Double>();
          otm.put(1L, 1.0);
          otm.put(2L, 2.0);

        for (Object thisObject : otm.keySet()) {
                System.out.println(otm.containsKey(thisObject));
        }     

您能否将您在 TreeMap 中输入的数据提供给我们。谢谢

这是 JavaDocs 中的 containsKey(Object key) 实现

包含键

boolean containsKey(对象键)

如果此映射包含指定键的映射,则返回 true。

更正式地说,当且仅当此映射包含键 k 的映射时才返回 true,使得 (key==null ? k==null : key.equals(k))。(最多可以有一个这样的映射。)

参数:

key - key whose presence in this map is to be tested Returns:
true if this map contains a mapping for the specified key Throws:
ClassCastException - if the key is of an inappropriate type for this map (optional)
NullPointerException - if the specified key is null and this map does not permit null keys (optional

希望有帮助。

于 2013-08-07T17:31:46.080 回答
0

您必须对支持进行了更改,entrySet()/Map.Entry从而更改了关键订单,从而导致搜索失败containsKey

于 2013-08-07T17:47:02.730 回答