package graph; import java.util.*; /** * Node is mutable and represents an object and the edges it has to other objects. Edges and * corresponding children cannot be null. See the Graph class for more details. */ public class Node { private E name; private Map>> edges; public static final boolean DEBUGGING = false; // Abstraction Function: // Node represents an object that has edges to and from other objects in the way that // each object "points" at another one. These edges have labels, given by the String keys // in edges. These labels are mapped to Nodes that have an incoming edge of label String. // Each Node has a name/data. If edges is empty, the Node has no connections to other // Nodes. // // Representation Invariant: // edges != null, name != null, !edges.containsKey(null), // !edges.containsValue(null) /** * Creates a new Node using the given data * * @param name the data of the Node being constructed * @spec.modifies this * @spec.effects Constructs a new Node with data name * @throws IllegalArgumentException if name is null */ public Node(E name) { if (name == null) { throw new IllegalArgumentException(); } this.name = name; edges = new HashMap>>(); checkRep(); } /** * Returns this Node's data * * @return This Node's data */ public E getName() { checkRep(); return name; } /** * Returns a map of the edge labels and corresponding child Nodes * * @return A Map of names of edges branching from this and their corresponding child Nodes */ public Map>> getEdges() { checkRep(); return edges; } /** * Returns an ordered set of edges from parent to child. * * @param child The desired edges' connected child node from this node * @spec.requires There must be an edge from this node to the child node * @return All edges from the parent to the child */ public List getEdgesTo(E child) { List list = new ArrayList(); Node childNode = new Node(child); for (F edge : edges.keySet()) { if (edges.get(edge).contains(childNode)) { list.add(edge); } } return list; } /** * Returns true if this and other are equal (two Nodes are equal if they have the * same data) * * @param other Checked if it is equal to this Node * @return True if this and other are equal, but false if not */ @Override public boolean equals(Object other) { if (!(other instanceof Node)) { return false; } Node node2 = (Node) other; return this.name.equals(node2.getName()); } /** * Returns this Node's hashCode * * @return This Node's hashCode */ @Override public int hashCode() { return this.name.hashCode(); } /** * Returns a String representation of this node * * @return String representing this node */ @Override public String toString() { return name.toString(); } /** * Throws an exception if the representation invariant is violated. */ private void checkRep() { assert name != null; assert edges != null; if (DEBUGGING) { if (!edges.isEmpty()) { // containsKey and containsValue threw NullPointerExceptions when checked for // null so I looped through everything one-by-one for (F label : edges.keySet()) { assert label != null; for (Node n : edges.get(label)) { assert n != null; } } } } } }