在JUNG图中创建冗余重复节点

时间:2018-03-10 18:38:06

标签: java neo4j jung

我在渲染Jung图时遇到问题 - 图表由于某种原因正在创建重复的节点。

我加载节点(两种不同类型到自定义Vertex类中(MovieVertex extends 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);
            } 

enter image description here 编辑:我将以下代码添加到Vertex自定义类来解决问题,更新图示例:

    @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();
    }

enter image description here

2 个答案:

答案 0 :(得分:1)

这是任何用作Map键的自定义Java类的常见问题(如JUNG Vertices所示)。除非您在自定义Vertex类中覆盖equalshashCode方法,否则您将获得重复项。如果您将MovieVertexPersonVertex个实例添加到java.util.Set或将其用作地图中的键,则会出现同样的问题。 也许您可以使用您的名称字段来计算hashCode的值并确定Vertices何时相等。

答案 1 :(得分:1)

正如Tom Nelson所提到的,如果你没有实施equals / hashCode,那么顶点将永远不同。一旦实现了这些,如果您尝试将相同的顶点添加到图形中,实际上会出现异常。

如果要为现有顶点添加边,则应保留自己的影片名称(或所需的任何键)到顶点的映射。然后在循环中,检查该映射中是否已有顶点,并为其添加新边。