我正在使用Google Guava in Version 21.0中的fith
。它非常适合我的用例而没有一个方面:持久性。该图似乎只在内存中。图表类没有实现common.graph
,这在issue posts中进行了解释。
Google介绍了three models to store the topology。第三种选择是:
单独的数据存储库(例如,数据库)存储拓扑
但这就是全部。我没有在包中找到任何方法来应用单独的数据存储库。有没有办法做到这一点?或者是使用Serializable
和nodes()
方法获取edges()
个节点和Set
边缘的唯一方法?如果我在这个类中实现Set
并通过调用Serializable
和addNode(Node)
(没有addAll方法)来恢复图形,我可以将它们保存在数据库中。但这似乎是一种解决方法。
感谢您的支持!
答案 0 :(得分:6)
简要回顾一下Guava的common.graph
类不是Serializable
的原因:Java序列化很脆弱,因为它取决于实现的细节,并且可以随时改变,所以我们不要不支持图表类型。
在短期内,您建议的解决方法可能是您最好的选择,尽管您需要小心存储边缘对象边缘的端点(源和目标),以便您能够重建你描述的图表。事实上,如果您拥有一个您满意的数据库并且您不需要担心与其他任何人进行互操作,那么从长远来看这也可能对您有用。
正如我在GitHub issue中提到的,另一个选择是将图表保持为某种文件格式。 (Guava本身并没有提供这样做的机制,但是JUNG一旦我可以获得3.0,我会继续使用common.graph
图表。我们注意到大多数图形文件格式(至少我熟悉的那些)对存储节点和边缘元数据的支持相当有限,所以你可能需要自己的文件格式(比如基于协议缓冲区的东西)。
答案 1 :(得分:2)
我发现存储图形的一种方法是通过DOT format,就像这样:
public class DOTWriter<INode, IEdge> {
public static String write(final Graph graph) {
StringBuilder sb = new StringBuilder();
sb.append("strict digraph G {\n");
for(INode n : graph.nodes()) {
sb.append(" \"" + n.getId() + "\n");
}
for(IEdge e : graph.edges()) {
sb.append(" \"" + e.getSource().getId() + "\" -> \"" + e.getTarget().getId() + "\" " + "\n");
}
sb.append("}");
return sb.toString();
}
}
这将产生类似
strict digraph G {
node_A;
node_B;
node_A -> node_B;
}
很容易阅读并再次在内存中建立图形。
如果您的节点是复杂对象,则应将它们分开存储。