我有以下对象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));
}
}
我有时会得到以下内容:
HASHCODE:true EQUALS:true CONTAINS: false N:foo X:foo比较:0
任何人都知道我做错了什么?我对这一切还不熟悉,所以如果我忽略了一些简单的事情,我会提前道歉(我知道hashCode()
对TreeMap
并不重要,但我想我会把它包括在内)
edit1:添加了compareTo()
方法信息。
答案 0 :(得分:5)
TreeSet不使用equals()来确定相等性。它使用Comparator(或Comparable)代替。为了使其正常工作,您必须遵循与equals 规则的一致性:
“比较器强加的排序c 在一组元素S上据说是 与ifals一致,当且仅当 c.compare(e1,e2)== 0具有相同的 布尔值为e1.equals(e2) S“中的每一个e1和e2。
我猜你没有遵循这个规则(你没有提供compareTo方法的实现)。如果未遵循规则,则树集将不具有Set的正常行为。
有关详细信息,请参阅http://eyalsch.wordpress.com/2009/11/23/comparators/。
- 编辑 -
现在您提供了compareTo实现,很明显它有一个缺陷。对于不相等的2个节点(并且具有相同的哈希码),它可以返回0。因此,您无法在TreeSet中添加具有相同哈希码的2个项目!
答案 1 :(得分:5)
这里有一些问题。
Object.equals
。使用@Override public boolean equals(Object obj)
。compareTo
中存在潜在的整数溢出错误。这可能是导致此特定错误的原因。它会扰乱排序,因此搜索可能不会成功。compareTo
方法声称如果哈希码恰好匹配,则两个实例是相等的(可能是一个难以捕获的错误,没有代码审查)。对于整数溢出问题,请参阅问题Why is my simple comparator broken?
答案 2 :(得分:0)
检查比较器。
可能依赖比较器的containsKey()
调用getEntry()
。如果它被破坏,你可能会得到不一致的结果。