2

我有以下对象Node

    private class Node implements Comparable<Node>(){
         private String guid();

         ...

         public boolean equals(Node o){
             return (this == o);
         }

         public int hashCode(){
              return guid.hashCode();
         }

         public int compareTo(Node o){
            return (this.hashCode() - o.hashCode());
         }

         ...

    }

我在下面使用它TreeMap

TreeMap<Node, TreeSet<Edge>> nodes = new TreeMap<Node, TreeSet<Edge>>();

现在,树形图用于一个名为的类中Graph,用于存储图中当前的节点,以及它们的一组边(来自类Edge)。我的问题是当我尝试执行时:

   public containsNode(n){
        for (Node x : nodes.keySet()) {
            System.out.println("HASH CODE: ");
            System.out.print(x.hashCode() == n.hashCode());
            System.out.println("EQUALS: ");
            System.out.print(x.equals(n));
            System.out.println("CONTAINS: ");
            System.out.print(nodes.containsKey(n));
            System.out.println("N: " + n);
            System.out.println("X: " + x);
            System.out.println("COMPARES: ");
            System.out.println(n.compareTo(x));
            }
        }

我有时会得到以下信息:

哈希码:真等于:真包含: N:foo X:foo 比较:0

任何人都知道我做错了什么?我对这一切还是陌生的,所以如果我忽略了一些简单的事情,我提前道歉(我知道hashCode()这对 来说并不重要TreeMap,但我想我会包括它)。

edit1:添加了compareTo()方法信息。

4

3 回答 3

5

TreeSet 不使用 equals() 来确定相等性。它改用 Comparator(或 Comparable)。为了使其正常工作,您必须遵循与 equals规则的一致性:

“当且仅当 c.compare(e1, e2)==0 与 e1.equals(e2) 对于每个S 中的 e1 和 e2”。

我猜你没有遵循这个规则(你没有提供 compareTo 方法的实现)。当不遵循该规则时,树集将不会有一个Set的正常行为。

有关详细信息,请参阅http://eyalsch.wordpress.com/2009/11/23/comparators/

- 编辑 -

现在您提供了 compareTo 实现,很明显它有一个缺陷。对于 2 个不相等的节点(并且具有相同的哈希码),它可能会返回 0。因此,您不能将具有相同哈希码的 2 个项目添加到 TreeSet 中!

于 2010-04-22T21:19:42.133 回答
5

这里有几件事是错误的。

  • 你没有覆盖Object.equals. 使用@Override public boolean equals(Object obj).
  • 中存在潜在的整数溢出错误compareTo。这可能是导致此特定错误的原因。它会打乱排序,因此搜索很可能不会成功。
  • compareTo方法声称如果哈希码恰好匹配,则两个实例相等(如果没有代码审查,这可能是一个难以捕捉的错误)。

对于整数溢出问题,请参阅问题为什么我的简单比较器坏了?

于 2010-04-22T21:30:02.877 回答
0

检查你的比较器。

可能依赖比较器的containsKey()调用。getEntry()如果它被破坏,您可能会得到不一致的结果。

于 2010-04-22T21:18:57.033 回答