Java:.equals() 对于集合失败(JGraphT)
我不明白这里出了什么问题。此测试失败:
@Test
public void testSimpleCase() {
assertTrue(JGraphtUtilities.graphEquality(ChooseRootTest.generateSimpleCaseGraph(), ChooseRootTest.generateSimpleCaseGraph()));
}
public static <V, E> boolean graphEquality(Graph<V, E> g0, Graph<V, E> g1) {
boolean result = true;
if (g0.edgeSet().equals(g1.edgeSet()) && g0.vertexSet().equals(g1.vertexSet())) {
for (E e : g0.edgeSet()) {
if (g0.getEdgeWeight(e) != g1.getEdgeWeight(e)) {
result = false;
}
}
}
else {
return false; //for the above test, this is what is returned
}
return result;
}
调试器显示该方法确定两个顶点集和边集不相等,因此返回 false。这怎么可能?
旁注:我正在尝试为 JGraphT 图编写相等性检查。这怎么可能还没有完成呢?
更新:我认为 DefaultWeightedEdge 不会覆盖 equals,所以这是行不通的。我采用了一种不同的方法来检查所有必要顶点之间是否存在边,现在它似乎有效。
I can't figure out what's going wrong here. This test fails:
@Test
public void testSimpleCase() {
assertTrue(JGraphtUtilities.graphEquality(ChooseRootTest.generateSimpleCaseGraph(), ChooseRootTest.generateSimpleCaseGraph()));
}
public static <V, E> boolean graphEquality(Graph<V, E> g0, Graph<V, E> g1) {
boolean result = true;
if (g0.edgeSet().equals(g1.edgeSet()) && g0.vertexSet().equals(g1.vertexSet())) {
for (E e : g0.edgeSet()) {
if (g0.getEdgeWeight(e) != g1.getEdgeWeight(e)) {
result = false;
}
}
}
else {
return false; //for the above test, this is what is returned
}
return result;
}
The debugger shows that the method decides that the two vertex sets and edge sets aren't equal, so it returns false. How is this possible?
Side note: I'm trying to write an equality check for JGraphT graphs. How is it possible that this hasn't been done already?
UPDATE: I think that DefaultWeightedEdge doesn't override equals, so that wouldn't work. I did a different way of checking that edges exist between all necessary vertices, and now it seems to work.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
根据 JavaDoc
DefaultWeightedEdge
尚未实现equals()
和hashCode()
,因此使用java.lang.Object
中定义的方法。这意味着具有相同值的两个DefaultWeightedEdge
对象a
和b
将不会返回true来自
a.equals(b)
。仅当a
和b
实际上引用同一个对象时,才会返回true
。您需要使用实现
.equals()
和hashCode()
的边缘实现类才能在此处获得有用的结果。According to the JavaDoc
DefaultWeightedEdge
hasn't implementedequals()
andhashCode()
and thus uses the methods defined injava.lang.Object
. This means that twoDefaultWeightedEdge
objectsa
andb
with the same values will not returntrue
froma.equals(b)
. That would only returntrue
ifa
andb
actually refer to the same object.You need to use an edge implementation class that implements
.equals()
andhashCode()
to get useful results here.我对JGraphT不熟悉,但我能想到两个问题。
首先,两组边相等意味着什么?是什么使两条边相等?如果我创建一个图,并分别创建一个相同的图,则两者可能具有相同的结构。但是,如果两条匹配边的边比较使用节点标识,则两条边将不“相等”。
其次,我在 JavaDocs 中注意到了这一点:
“图实现可能会维护特定的集合排序(例如通过 LinkedHashSet)以进行确定性迭代,但这不是必需的。依赖此行为的调用者有责任仅使用支持它的图形实现。”
我会尝试(至少为了理智)确保这两个集合彼此包含,因为 equals 可能没有正确实现(例如,它可能会考虑顺序)。
I'm not familiar with JGraphT, but there are two issues I can think of.
First, what does it mean for two sets of edges to be equivalent? What is it that makes two edges equivalent? If I create a graph, and create an identical graph separately, both might have the same structure. But if edge comparison of two matching edges uses the node identities, the two edges would not be "equal".
Second, I've noted this in the JavaDocs:
"The graph implementation may maintain a particular set ordering (e.g. via LinkedHashSet) for deterministic iteration, but this is not required. It is the responsibility of callers who rely on this behavior to only use graph implementations which support it."
I would try (at least for sanity) to make sure that the two sets contain each other, as it is possible that equals is not implemented correctly (e.g., it may take order into account).