package graphs; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; /** * An undirected graph stored as an adjacency list. * * @param The vertex type * @param The edge type. Must be a subtype of {@link Edge}. */ public class AdjacencyListUndirectedGraph> implements KruskalGraph { private final List allEdges; protected final Map> adjacencyList; /** * Constructs a new graph with the given edges. * * Ignores duplicate edges (edges that are exactly equal according to the {@code equals} method, * or edges that would be equal if their directions were flipped). * * @param edges The edges in the graph. * @throws NullPointerException if edges is null, contains null entries, or contains edges with null vertices */ public AdjacencyListUndirectedGraph(Collection edges) { this.allEdges = new ArrayList<>(); this.adjacencyList = new HashMap<>(); edges.forEach(e -> { if (e.from() == null || e.to() == null) { throw new NullPointerException( "Graph edge contains a null vertex, but null vertices are not supported."); } if (adjacencyList.computeIfAbsent(e.from(), v -> new HashSet<>()).add(e)) { allEdges.add(e); } adjacencyList.computeIfAbsent(e.to(), v -> new HashSet<>()).add(e.reversed()); }); } @Override public Set outgoingEdgesFrom(V vertex) { return Collections.unmodifiableSet(adjacencyList.getOrDefault(vertex, Set.of())); } @Override public Set allVertices() { return Collections.unmodifiableSet(this.adjacencyList.keySet()); } @Override public List allEdges() { return Collections.unmodifiableList(this.allEdges); } }