在 JUNG 图中创建冗余重复节点
Redundant duplicate nodes being created in JUNG graph
我在渲染 Jung 图时遇到问题 - 该图出于某种原因创建了重复的节点。
我加载节点(两种不同类型的自定义顶点 class(MovieVertex 扩展 RootNode 实现 NodeInfo,PersonVertex 扩展 RootNode 实现 NodeInfo)- RootNode 有一个名称字段,我使用以下代码:
DirectedSparseGraph<NodeInfo,String> g = new DirectedSparseGraph<NodeInfo, String>();
// Code to read node data from a Neo4j graph database
List<Map<String, Object>> nodes = grapher.read(cql);
try (Session session = grapher.driver.session()){
StatementResult result = session.run(cql2);
while (result.hasNext()) {
Record record = result.next();
String targetNode = record.get(1).get("title").toString();
String sourceNode = record.get(0).get("name").toString();
String tagline = record.get(1).get("tagline").toString();
String released = record.get(1).get("released").toString();
int born = record.get(0).get("born").asInt();
String rel = sourceNode + "-ACTED_IN-"+ targetNode;
//The problem is probably here - it is creating duplicate vertices for the same data
MovieVertex mv = new MovieVertex(targetNode,tagline,released);
PersonVertex pv = new PersonVertex(sourceNode,born);
g.addVertex(pv);
g.addVertex(mv);
g.addEdge(rel, pv, mv);
ISOMLayout<NodeInfo,String> layout = new ISOMLayout<NodeInfo,String>(g);
VisualizationViewer<NodeInfo,String> vv =
new VisualizationViewer<NodeInfo,String>(layout, new Dimension(800,800));
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
JFrame frame = new JFrame();
frame.getContentPane().add(vv);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
编辑:我将以下代码添加到 Vertex 自定义 classes 以解决问题,更新图形示例:
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof MovieVertex)) {
return false;
}
MovieVertex mv = (MovieVertex) o;
return new EqualsBuilder()
.append(title, mv.title)
.append(tagline, mv.tagline)
.append(released, mv.released)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(title)
.append(tagline)
.append(released)
.toHashCode();
}
这是任何用作 Map
键(如 JUNG 顶点)的自定义 Java class 的常见问题。除非您在自定义 Vertex class 中覆盖 equals
和 hashCode
方法,否则您将得到重复项。如果将 MovieVertex
或 PersonVertex
实例添加到 java.util.Set
或将它们用作 Map 中的键,您会遇到同样的问题。
也许您可以使用您的名称字段来计算 hashCode 的值并确定顶点何时相等。
正如 Tom Nelson 提到的,如果您不实施 equals
/hashCode
,顶点将始终不同。一旦你实现了这些,如果你试图将相同的顶点添加到图中,你实际上会得到一个异常。
如果您想向现有顶点添加边,您应该保留自己的电影名称(或任何您想要的键)到顶点的映射。然后在你的循环中,检查你是否已经在该地图中有一个顶点,并向其添加一个新边。
我在渲染 Jung 图时遇到问题 - 该图出于某种原因创建了重复的节点。
我加载节点(两种不同类型的自定义顶点 class(MovieVertex 扩展 RootNode 实现 NodeInfo,PersonVertex 扩展 RootNode 实现 NodeInfo)- RootNode 有一个名称字段,我使用以下代码:
DirectedSparseGraph<NodeInfo,String> g = new DirectedSparseGraph<NodeInfo, String>();
// Code to read node data from a Neo4j graph database
List<Map<String, Object>> nodes = grapher.read(cql);
try (Session session = grapher.driver.session()){
StatementResult result = session.run(cql2);
while (result.hasNext()) {
Record record = result.next();
String targetNode = record.get(1).get("title").toString();
String sourceNode = record.get(0).get("name").toString();
String tagline = record.get(1).get("tagline").toString();
String released = record.get(1).get("released").toString();
int born = record.get(0).get("born").asInt();
String rel = sourceNode + "-ACTED_IN-"+ targetNode;
//The problem is probably here - it is creating duplicate vertices for the same data
MovieVertex mv = new MovieVertex(targetNode,tagline,released);
PersonVertex pv = new PersonVertex(sourceNode,born);
g.addVertex(pv);
g.addVertex(mv);
g.addEdge(rel, pv, mv);
ISOMLayout<NodeInfo,String> layout = new ISOMLayout<NodeInfo,String>(g);
VisualizationViewer<NodeInfo,String> vv =
new VisualizationViewer<NodeInfo,String>(layout, new Dimension(800,800));
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller());
JFrame frame = new JFrame();
frame.getContentPane().add(vv);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
@Override
public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof MovieVertex)) {
return false;
}
MovieVertex mv = (MovieVertex) o;
return new EqualsBuilder()
.append(title, mv.title)
.append(tagline, mv.tagline)
.append(released, mv.released)
.isEquals();
}
@Override
public int hashCode() {
return new HashCodeBuilder(17, 37)
.append(title)
.append(tagline)
.append(released)
.toHashCode();
}
这是任何用作 Map
键(如 JUNG 顶点)的自定义 Java class 的常见问题。除非您在自定义 Vertex class 中覆盖 equals
和 hashCode
方法,否则您将得到重复项。如果将 MovieVertex
或 PersonVertex
实例添加到 java.util.Set
或将它们用作 Map 中的键,您会遇到同样的问题。
也许您可以使用您的名称字段来计算 hashCode 的值并确定顶点何时相等。
正如 Tom Nelson 提到的,如果您不实施 equals
/hashCode
,顶点将始终不同。一旦你实现了这些,如果你试图将相同的顶点添加到图中,你实际上会得到一个异常。
如果您想向现有顶点添加边,您应该保留自己的电影名称(或任何您想要的键)到顶点的映射。然后在你的循环中,检查你是否已经在该地图中有一个顶点,并向其添加一个新边。