Java树映射包含一个键,但containsKey调用返回false(即使键是完全相同的未更改对象)

Java树映射包含一个键,但containsKey调用返回false(即使键是完全相同的未更改对象),java,map,treemap,containskey,keyset,Java,Map,Treemap,Containskey,Keyset,为什么可以循环树映射的键集,并获得。containsKey==false for (Object thisObject : map.keySet()) { if (!map.containsKey(thisObject)) { System.out.println("This line should be never reached."); } } 经过大量不同的迭代和调用,这一行被命中。map.get(thisObject)将返回null。 但是调试显示键(相

为什么可以循环树映射的
键集
,并获得
。containsKey==false

for (Object thisObject : map.keySet()) {
    if (!map.containsKey(thisObject)) {
        System.out.println("This line should be never reached.");
    }
}
经过大量不同的迭代和调用,这一行被命中。
map.get(thisObject)
将返回
null
。 但是调试显示键(相同的引用、值和哈希值)和实际值在映射中。地图是一个小的(25个元素)
TreeMap

更新:

正如所猜测的,在构建树映射时使用了一个自定义排序
比较器
(没有看到它,因为它是从另一个类构建的)。这个比较器(我猜)只是从

更改比较器

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

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

因此:

25151l, 1.7583805400614032
24827l, 1.7583805400614032
它失败了


谢谢你的帮助

我刚刚执行了代码,这个案例确实向我返回了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));
        }     

希望能有所帮助。

您必须对backing
entrySet()/Map.Entry
进行了更改,从而更改了键顺序,从而导致搜索失败
containsKey
这些实现类中的大多数都依赖于hashCode()和equals()的支持和正确性

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


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

您可以尝试将==更改为.equals吗?@RameshK我的意思是,OP已经确认它是同一个ref,所以
==
不应该有问题,应该有吗?失败的键值是什么?因为它很小,所以您可以添加一个包含所有键值的键值,以便我们可以运行它吗?失败的一种方法是向
树映射
构造函数提供一个
比较器
,它打破了
比较器
契约,例如,对于相等的值,不返回
0
。如果问题出在OP添加的特定对中,而该对不在您的示例中,该怎么办?关键是OP知道它应该返回true,但想知道为什么他的特定案例不是。尝试其他一些随机案例根本不能回答这个问题。@DennisMeng我很想了解这样一对特殊的组合。我的观点是OP可能没有正确地实现它。这就是为什么我想看看具体的案例。你遇到过这样的情况吗?如果是的话,如果你能让我知道同样的情况,我将不胜感激。我想,但是“确定你没有犯x错误”和“我尝试了另一个案例,对我来说效果很好”之间是有区别的。当然,但在这里数百万个电话返回false之后,情况确实如此。将尝试提供一个SSCCE…那将是非常棒的。因为如果hashcode在调试器中是相同的,我也很想知道相同的内容。Long的hashcode是基于它的值
public int hashcode(){return(int)(value^(value>>>32));}
          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));
        }     
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