Guava ValueGraph 的简单示例

Simple example of Guava ValueGraph

我正在寻找 Guava ValueGraph 的简单示例。类似于:

class GraphNode {
  String name;
  String value;
  // Do I need to override equals & hashcode methods here??

}

class GraphUser {
  public ValueGraph<GraphNode,Double> createGraph(){
    ValueGraph<GraphNode,Double> graph = ValueGraphBuilder.directed.build();
    // How do I add the nodes to graph??
    // How do I add the edges to graph?
  }
}
  1. 如何创建以自定义对象为节点的图表?
  2. 如何向图形添加节点和边?
  3. 我是否必须覆盖自定义节点中的 equals 和 hashCode 方法 class?

一个简单的例子会很有帮助。

Guava wiki给出了以下使用ValueGraph的例子:

MutableValueGraph<Integer, Double> weightedGraph = ValueGraphBuilder.directed().build();
weightedGraph.addNode(1);
weightedGraph.putEdgeValue(2, 3, 1.5);  // also adds nodes 2 and 3 if not already present
weightedGraph.putEdgeValue(3, 5, 1.5);  // edge values (like Map values) need not be unique
...
weightedGraph.putEdgeValue(2, 3, 2.0);  // updates the value for (2,3) to 2.0

我会尽力按照您提出的顺序回答您的其他问题:

  1. 如何创建以自定义对象为节点的图表?

    public final class GraphNode {
      private final String name;
      private final int age;
    
      GraphNode(String name, int age) {
        this.name = Objects.requireNonNull(name, "name");
        this.age = age;
      }
    
      public String name() {
        return name;
      }
    
      public int age() {
        return age;
      }
    
      @Override
      public boolean equals(Object other) {
        if (other instanceof GraphNode) {
          GraphNode that = (GraphNode) other;
          return this.name.equals(that.name)
              && this.age == that.age;
        }
        return false;
      }
    
      @Override
      public int hashCode() {
        return Objects.hash(name, age);
      }
    
      @Override
      public String toString() {
        return "(" + name + ", " + age + ")";
      }
    }
    

稍后将详细介绍如何使用此 class 的对象创建值图。

  1. 如何向图形添加节点和边?

    MutableValueGraph<GraphNode, Double> weightedGraph = ValueGraphBuilder.directed().build();
    GraphNode a = new GraphNode("Jonathan", 20);
    GraphNode b = new GraphNode("Nicolas", 40);
    GraphNode c = new GraphNode("Georgia", 30);
    weightedGraph.putEdgeValue(a, b, 2.0);
    weightedGraph.putEdgeValue(a, c, 4.5);
    

    这将生成如下图(箭头向下):

           (Jonathan, 20)
                 / \
              2.0   4.5
               /     \
    (Nicolas, 40)   (Georgia, 30)
    
  2. 我是否必须覆盖自定义节点中的 equals 和 hashCode 方法 class?

    这不是绝对必要的,但强烈建议这样做,否则,对于以下代码示例,图表可能看起来与您预期的不同。

    MutableValueGraph<GraphNode, Double> weightedGraph = ValueGraphBuilder.directed().build();
    GraphNode a = new GraphNode("Jonathan", 20);
    GraphNode b = new GraphNode("Nicolas", 40);
    GraphNode c = new GraphNode("Georgia", 30);
    weightedGraph.putEdgeValue(a, b, 2.0);
    weightedGraph.putEdgeValue(a, c, 4.5);
    weightedGraph.putEdgeValue(b, new GraphNode("Luke", 10), 6.0);
    weightedGraph.putEdgeValue(c, new GraphNode("Luke", 10), 1.5);
    

    使用 GraphNode 中的自定义 equals()hashCode() 实现,图形将产生以下预期形状:

            (Jonathan, 20)
                 / \
              2.0   4.5
               /     \
    (Nicolas, 40)   (Georgia, 30)
               \     /
              6.0   1.5
                 \ /
             (Luke, 10)
    

    但是如果没有equals()hashCode(),值图就无法判断这两个new GraphNode("Luke", 10)在逻辑上是同一个节点,所以会产生如下错误形状:

            (Jonathan, 20)
                 / \
              2.0   4.5
               /     \
    (Nicolas, 40)   (Georgia, 30)
              |       |
             6.0     1.5
              |       |
       (Luke, 10)   (Luke, 10)
    

希望对您有所帮助!