diff options
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/graph')
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java | 118 | ||||
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java | 62 | ||||
| -rw-r--r-- | BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java | 26 |
3 files changed, 172 insertions, 34 deletions
diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java index 513044e..e583210 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java @@ -5,6 +5,7 @@ import java.io.OutputStream; import java.io.PrintStream; import java.util.HashMap; import java.util.HashSet; +import java.util.InputMismatchException; import java.util.Map; import java.util.Map.Entry; import java.util.Scanner; @@ -30,36 +31,79 @@ public class AdjacencyMap<T> { * @return An adjacency map defined by the text */ public static AdjacencyMap<Integer> fromStream(InputStream stream) { - Scanner inputSource = new Scanner(stream); - inputSource.useDelimiter("\n"); - - // First, read in number of vertices - int numVertices = Integer.parseInt(inputSource.next()); - - Set<Integer> vertices = new HashSet<>(); - IntStream.range(0, numVertices) - .forEach(element -> vertices.add(element)); + if (stream == null) { + throw new NullPointerException( + "Input source must not be null"); + } // Create the adjacency map - AdjacencyMap<Integer> adjacencyMap = new AdjacencyMap<>(vertices); + AdjacencyMap<Integer> adjacencyMap; - GenHolder<Integer> row = new GenHolder<>(0); + try (Scanner inputSource = new Scanner(stream)) { + inputSource.useDelimiter("\n"); - inputSource.forEachRemaining((strang) -> { - String[] parts = strang.split(" "); - int column = 0; + int numVertices; - for (String part : parts) { - adjacencyMap.setWeight(row.unwrap(number -> number), - column, Integer.parseInt(part)); + String possibleVertices = inputSource.next(); - column++; + try { + // First, read in number of vertices + numVertices = Integer.parseInt(possibleVertices); + } catch (NumberFormatException nfex) { + throw new InputMismatchException( + "The first line must contain the number of vertices. " + + possibleVertices + + " is not a valid number"); } - row.transform((number) -> number + 1); - }); + if (numVertices <= 0) { + throw new InputMismatchException( + "The number of vertices must be greater than 0"); + } + + Set<Integer> vertices = new HashSet<>(); + + IntStream.range(0, numVertices) + .forEach(element -> vertices.add(element)); + + adjacencyMap = new AdjacencyMap<>(vertices); + + GenHolder<Integer> row = new GenHolder<>(0); + + inputSource.forEachRemaining((strang) -> { + String[] parts = strang.split(" "); + + if (parts.length != numVertices) { + throw new InputMismatchException( + "Must specify a weight for all " + numVertices + + " vertices"); + } + + int column = 0; - inputSource.close(); + for (String part : parts) { + int columnWeight; + + try { + columnWeight = Integer.parseInt(part); + } catch (NumberFormatException nfex) { + throw new InputMismatchException( + "" + part + " is not a valid weight."); + } + + adjacencyMap.setWeight(row.unwrap(number -> number), + column, columnWeight); + + column++; + } + + row.transform((number) -> { + int newNumber = number + 1; + + return newNumber; + }); + }); + } return adjacencyMap; } @@ -76,6 +120,10 @@ public class AdjacencyMap<T> { * The set of vertices to create a map from */ public AdjacencyMap(Set<T> vertices) { + if (vertices == null) { + throw new NullPointerException("Vertices must not be null"); + } + vertices.forEach(vertex -> { Map<T, Integer> vertexRow = new HashMap<>(); @@ -97,6 +145,7 @@ public class AdjacencyMap<T> { adjacencyMap.entrySet().forEach(mapEntry -> { Set<Entry<T, Integer>> entryVertices = mapEntry.getValue().entrySet(); + entryVertices.forEach(targetVertex -> { int leftValue = targetVertex.getValue(); int rightValue = adjacencyMap.get(targetVertex.getKey()) @@ -122,6 +171,22 @@ public class AdjacencyMap<T> { * The weight of the edge */ public void setWeight(T sourceVertex, T targetVertex, int edgeWeight) { + if (sourceVertex == null) { + throw new NullPointerException( + "Source vertex must not be null"); + } else if (targetVertex == null) { + throw new NullPointerException( + "Target vertex must not be null"); + } + + if (!adjacencyMap.containsKey(sourceVertex)) { + throw new IllegalArgumentException("Source vertex " + + sourceVertex + " isn't present in map"); + } else if (!adjacencyMap.containsKey(targetVertex)) { + throw new IllegalArgumentException("Target vertex " + + targetVertex + " isn't present in map"); + } + adjacencyMap.get(sourceVertex).put(targetVertex, edgeWeight); } @@ -145,11 +210,16 @@ public class AdjacencyMap<T> { /** * Convert an adjacency map back into a stream * - * @param outputSource + * @param outputSink * The stream to convert to */ - public void toStream(OutputStream outputSource) { - PrintStream outputPrinter = new PrintStream(outputSource); + public void toStream(OutputStream outputSink) { + if (outputSink == null) { + throw new NullPointerException( + "Output source must not be null"); + } + + PrintStream outputPrinter = new PrintStream(outputSink); adjacencyMap.entrySet().forEach(sourceVertex -> { sourceVertex.getValue().entrySet() diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java index 44aa8e7..58a233a 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java @@ -30,6 +30,14 @@ public class Edge<T> { * The distance between initial and terminal edge */ public Edge(T initialNode, T terminalNode, int distance) { + if (initialNode == null) { + throw new NullPointerException( + "Initial node must not be null"); + } else if (terminalNode == null) { + throw new NullPointerException( + "Terminal node must not be null"); + } + this.source = initialNode; this.target = terminalNode; this.distance = distance; @@ -68,4 +76,58 @@ public class Edge<T> { return " first vertex " + source + " to vertex " + target + " with distance: " + distance; } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#hashCode() + */ + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + distance; + result = prime * result + + ((source == null) ? 0 : source.hashCode()); + result = prime * result + + ((target == null) ? 0 : target.hashCode()); + return result; + } + + /* + * (non-Javadoc) + * + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } else if (obj == null) { + return false; + } else if (getClass() != obj.getClass()) { + return false; + } else { + + Edge<?> other = (Edge<?>) obj; + + if (distance != other.distance) { + return false; + } else if (source == null) { + if (other.source != null) { + return false; + } + } else if (!source.equals(other.source)) { + return false; + } else if (target == null) { + if (other.target != null) { + return false; + } + } else if (!target.equals(other.target)) { + return false; + } + + return true; + } + } } diff --git a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java index 5172df5..f6bfc85 100644 --- a/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java +++ b/BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java @@ -53,9 +53,7 @@ public class Graph<T> { if (sourceVertex == null) { throw new NullPointerException( "The source vertex cannot be null"); - } - - if (targetVertex == null) { + } else if (targetVertex == null) { throw new NullPointerException( "The target vertex cannot be null"); } @@ -79,19 +77,25 @@ public class Graph<T> { * Execute an action for all edges of a specific vertex matching * conditions * - * @param source + * @param sourceVertex * The vertex to test edges for * @param edgeMatcher * The conditions an edge must match * @param edgeAction * The action to execute for matching edges */ - public void forAllEdgesMatchingAt(T source, + public void forAllEdgesMatchingAt(T sourceVertex, BiPredicate<T, Integer> edgeMatcher, BiConsumer<T, Integer> edgeAction) { - getEdges(source).forEach((tgt, weight) -> { - if (edgeMatcher.test(tgt, weight)) { - edgeAction.accept(tgt, weight); + if (edgeMatcher == null) { + throw new NullPointerException("Matcher must not be null"); + } else if (edgeAction == null) { + throw new NullPointerException("Action must not be null"); + } + + getEdges(sourceVertex).forEach((targetVertex, vertexWeight) -> { + if (edgeMatcher.test(targetVertex, vertexWeight)) { + edgeAction.accept(targetVertex, vertexWeight); } }); } @@ -107,6 +111,9 @@ public class Graph<T> { // Can't find edges for a null source if (source == null) { throw new NullPointerException("The source cannot be null."); + } else if (!backingGraph.containsKey(source)) { + throw new IllegalArgumentException( + "Vertex " + source + " is not in graph"); } return Collections.unmodifiableMap(backingGraph.get(source)); @@ -213,8 +220,7 @@ public class Graph<T> { if (sourceVertex == null) { throw new NullPointerException( "The source vertex cannot be null"); - } - if (targetVertex == null) { + } else if (targetVertex == null) { throw new NullPointerException( "The target vertex cannot be null"); } |
