在标题为GraphStream的教程中

Storing, retrieving and displaying data in graphs


它指出:-

Other ways to store data on graphs
Sometimes you want to create your own graph structure and inherit the Node and Edge classes to create your own. In this case you will probably not store the data under the form of key-value attributes but inside fields of the classes you define. Both ways, key-value or inheritance, have their advantages and drawbacks.


我正在尝试继承(通过扩展org.graphstream.graph.implementations.SingleNode

我的代码测试失败

org.graphstream.graph.ElementNotFoundException


我创建两个自定义“ DataNode”,如下所示:

final Node dataNode1 = DataNode.builder().graph(GRAPH).id("One").stringData("StringData_1").integerData(1).build();
final Node dataNode2 = DataNode.builder().graph(GRAPH).id("Two").stringData("StringData_2").integerData(2).build();


然后尝试在它们之间创建一个“边缘”。

GRAPH.addEdge("Some", dataNode1, dataNode2);


我的图定义如下:

private static final SingleGraph GRAPH = new SingleGraph("Data");


配置如下:

GRAPH.setStrict(false);
GRAPH.setAutoCreate(true);
GRAPH.addAttribute("ui.quality");
GRAPH.addAttribute("ui.antialias");


如何利用继承来存储自定义数据属性

// https://mvnrepository.com/artifact/org.graphstream/gs-core
compile group: 'org.graphstream', name: 'gs-core', version: '1.3'
// https://mvnrepository.com/artifact/org.graphstream/gs-ui
compile group: 'org.graphstream', name: 'gs-ui', version: '1.3'


我的DataNode类类似于:

public class DataNode extends SingleNode {

    private final String mStringData;
    private final Integer mIntegerData;

    public DataNode(final AbstractGraph graph, final String id, final Builder builder) {
        super(graph, id);
        this.mStringData = builder.getStringData();
        this.mIntegerData = builder.getIntegerData();
    }

    /**
     * @return the mStringData
     */
    public String getStringData() {
        return mStringData;
    }

    /**
     * @return the mIntegerData
     */
    public Integer getIntegerData() {
        return mIntegerData;
    }

    public static Builder builder() {

        return new Builder();
    }

    public static class Builder {

        private AbstractGraph graph;
        private String id;

        private String mStringData;
        private Integer mIntegerData;

        /**
         * @param graph
         *            the graph to set
         */
        public Builder graph(final AbstractGraph graph) {
            this.graph = graph;
            return this;
        }

        /**
         * @param id
         *            the id to set
         */
        public Builder id(final String id) {
            this.id = id;
            return this;
        }

        /**
         * @param mStringData
         *            the mStringData to set
         */
        public Builder stringData(final String mStringData) {
            this.mStringData = mStringData;
            return this;
        }

        /**
         * @param mIntegerData
         *            the mIntegerData to set
         */
        public Builder integerData(final Integer mIntegerData) {
            this.mIntegerData = mIntegerData;
            return this;
        }

        /**
         * @return the graph
         */
        public AbstractGraph getGraph() {
            return graph;
        }

        /**
         * @return the id
         */
        public String getId() {
            return id;
        }

        /**
         * @return the mStringData
         */
        public String getStringData() {
            return mStringData;
        }

        /**
         * @return the mIntegerData
         */
        public Integer getIntegerData() {
            return mIntegerData;
        }

        public DataNode build() {
            return new DataNode(graph, id, this);
        }
    }
}

最佳答案

如果您并非绝对需要节点子类的字符串和整数字段为final,则可以为该图设置新的节点工厂。

您的扩展节点会更简单:

class DataNode extends SingleNode {
    private  String mStringData;
    private  Integer mIntegerData;
    public DataNode( AbstractGraph graph, final String id) {
        super(graph, id);
    }
    public void setStringData(String mStringData) {
        this.mStringData = mStringData;
    }
    public void setIntegerData(Integer mIntegerData) {
        this.mIntegerData = mIntegerData;
    }
    public String getStringData() {
        return mStringData;
    }
    public Integer getIntegerData() {
        return mIntegerData;
    }
}


然后,您可以使用节点工厂:

GRAPH.setNodeFactory(new NodeFactory<Node>() {
    @Override
    public Node newInstance(String id, Graph graph) {
        return new DataNode((AbstractGraph) graph, id);
    }
});


或Java 8版本:

GRAPH.setNodeFactory((id, graph) -> new DataNode((AbstractGraph)graph, id));


最终创建节点,然后设置属性(这就是为什么它们不能成为最终属性的原因):

final Node dataNode1 = GRAPH.addNode("One");
((DataNode)dataNode1).setStringData("StringData_1");
((DataNode)dataNode1).setIntegerData(1);

final Node dataNode2 = GRAPH.addNode("Twi");
((DataNode)dataNode1).setStringData("StringData_2");
((DataNode)dataNode1).setIntegerData(2);

GRAPH.addEdge("Some", dataNode1, dataNode2);

10-07 16:17