summaryrefslogtreecommitdiff
path: root/BJC-Utils2/src/main/java/bjc/utils/graph
diff options
context:
space:
mode:
Diffstat (limited to 'BJC-Utils2/src/main/java/bjc/utils/graph')
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/AdjacencyMap.java118
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/Edge.java62
-rw-r--r--BJC-Utils2/src/main/java/bjc/utils/graph/Graph.java26
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");
}