在Java中,想要创建一个包含相等顶点/边的简单图形(一个不包含图形循环或多边的未加权无向图)。
我有两个Java类,一个用于顶点:
class Vertex {
private int field;
public Vertex(int field) {
this.field = field;
}
@Override
public boolean equals(Object obj) {
if (obj.getClass().getPackage()
.equals(this.getClass().getPackage())
&& obj.getClass().getName()
.equals(this.getClass().getName())) {
Vertex vertex = (Vertex) obj;
if (this.field == vertex.field)
return true;
}
// Else
return false;
}
@Override
public int hashCode() {
// No need for a perfect hash
return this.field;
}
}
边缘的一个类:
class Edge {
private int field;
public Edge(int field) {
this.field = field;
}
@Override
public boolean equals(Object obj) {
if (obj.getClass().getPackage()
.equals(this.getClass().getPackage())
&& obj.getClass().getName()
.equals(this.getClass().getName())) {
Edge edge = (Edge) obj;
if (this.field == edge.field)
return true;
}
// Else
return false;
}
@Override
public int hashCode() {
// No need for a perfect hash
return this.field;
}
}
我目前使用JGraphT library。但是在开始这段代码之后我遇到了IllegalArgumentException: "loops not allowed"
:
// Define a EdgeFactory
EdgeFactory<Vertex, Edge> BOND_FACTORY = new EdgeFactory<Vertex, Edge>() {
@Override
public Edge createEdge(Vertex sourceVertex, Vertex targetVertex) {
return new Edge(2);
}
};
// Create the graph
SimpleGraph<Vertex, Edge> graph = new SimpleGraph<Vertex, Edge>(
BOND_FACTORY);
// Create vertexes
Vertex v1 = new Vertex(1);
Vertex v2 = new Vertex(1);
// Add them to the graph
graph.addVertex(v1);
graph.addVertex(v2);
graph.addEdge(v1, v2);
问题是我尝试将v2
添加到图表中,但因为v1.equals(v2) == true
v2
从未添加到图表中。来自lib的JavaDoc:
如果尚未存在,则将指定的顶点添加到此图形中。更正式地说,如果此图形不包含u.equals(v)的顶点u,则将指定的顶点v添加到此图形中。
此检查已实施here。
但是,我如何才能完成我想要做的事情?我可以在这个库中使用另一个实现,或者更改equals()
方法是个好主意吗?
答案 0 :(得分:1)
似乎对你来说,示例中的顶点v1和v2是可区分的。然后你必须确保它们也可以与图形区分开来。换句话说,请确保v1.equals(v2)返回false。 您可能需要考虑向Vertex添加成员变量“id”(或其他内容),并在该变量上添加equals和hashcode。该成员变量的契约是两个具有相同id的顶点相等。
如果然后创建两个具有相同字段但具有不同ID的顶点,则v1.equals(v2)将为false,并且两个Vertex对象表示图形中的不同顶点。例如:
Vertex v1 = new Vertex("a", 1);
Vertex v2 = new Vertex("b", 1);
Vertex的构造函数必须如下所示:
public Vertex(String id, int field) {
this.id = id;
this.field = field;
}
另一个解决方案是简单地从Vertex中删除hashcode和equals方法,以便使用Object中的继承方法,在这种情况下,两个Vertex实例相等,当且仅当它们引用同一个对象时(即内存)地址)。
Edge类也是如此。我不太确定你打算如何使用Edge的字段属性,但我只是删除它以避免遇到同样的问题。