001/* 002 * Copyright (C) 2016 The Guava Authors 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package com.google.common.graph; 018 019import com.google.common.annotations.Beta; 020import com.google.common.base.Function; 021import com.google.common.collect.Maps; 022import java.util.Map; 023import java.util.Set; 024import javax.annotation.Nullable; 025 026/** 027 * This class provides a skeletal implementation of {@link ValueGraph}. It is recommended to extend 028 * this class rather than implement {@link ValueGraph} directly. 029 * 030 * <p>The methods implemented in this class should not be overridden unless the subclass admits a 031 * more efficient implementation. 032 * 033 * @author James Sexton 034 * @param <N> Node parameter type 035 * @param <V> Value parameter type 036 * @since 20.0 037 */ 038@Beta 039public abstract class AbstractValueGraph<N, V> extends AbstractBaseGraph<N> 040 implements ValueGraph<N, V> { 041 042 @Override 043 public Graph<N> asGraph() { 044 return new AbstractGraph<N>() { 045 @Override 046 public Set<N> nodes() { 047 return AbstractValueGraph.this.nodes(); 048 } 049 050 @Override 051 public Set<EndpointPair<N>> edges() { 052 return AbstractValueGraph.this.edges(); 053 } 054 055 @Override 056 public boolean isDirected() { 057 return AbstractValueGraph.this.isDirected(); 058 } 059 060 @Override 061 public boolean allowsSelfLoops() { 062 return AbstractValueGraph.this.allowsSelfLoops(); 063 } 064 065 @Override 066 public ElementOrder<N> nodeOrder() { 067 return AbstractValueGraph.this.nodeOrder(); 068 } 069 070 @Override 071 public Set<N> adjacentNodes(N node) { 072 return AbstractValueGraph.this.adjacentNodes(node); 073 } 074 075 @Override 076 public Set<N> predecessors(N node) { 077 return AbstractValueGraph.this.predecessors(node); 078 } 079 080 @Override 081 public Set<N> successors(N node) { 082 return AbstractValueGraph.this.successors(node); 083 } 084 085 @Override 086 public int degree(N node) { 087 return AbstractValueGraph.this.degree(node); 088 } 089 090 @Override 091 public int inDegree(N node) { 092 return AbstractValueGraph.this.inDegree(node); 093 } 094 095 @Override 096 public int outDegree(N node) { 097 return AbstractValueGraph.this.outDegree(node); 098 } 099 }; 100 } 101 102 @Override 103 public final boolean equals(@Nullable Object obj) { 104 if (obj == this) { 105 return true; 106 } 107 if (!(obj instanceof ValueGraph)) { 108 return false; 109 } 110 ValueGraph<?, ?> other = (ValueGraph<?, ?>) obj; 111 112 return isDirected() == other.isDirected() 113 && nodes().equals(other.nodes()) 114 && edgeValueMap(this).equals(edgeValueMap(other)); 115 } 116 117 @Override 118 public final int hashCode() { 119 return edgeValueMap(this).hashCode(); 120 } 121 122 /** Returns a string representation of this graph. */ 123 @Override 124 public String toString() { 125 return "isDirected: " 126 + isDirected() 127 + ", allowsSelfLoops: " 128 + allowsSelfLoops() 129 + ", nodes: " 130 + nodes() 131 + ", edges: " 132 + edgeValueMap(this); 133 } 134 135 private static <N, V> Map<EndpointPair<N>, V> edgeValueMap(final ValueGraph<N, V> graph) { 136 Function<EndpointPair<N>, V> edgeToValueFn = 137 new Function<EndpointPair<N>, V>() { 138 @Override 139 public V apply(EndpointPair<N> edge) { 140 return graph.edgeValueOrDefault(edge.nodeU(), edge.nodeV(), null); 141 } 142 }; 143 return Maps.asMap(graph.edges(), edgeToValueFn); 144 } 145}