Reputation: 7
I am trying to implement a graph using HashMap where I store the nodes (vertices) on the key column and the adjacent nodes ( adjacent list ) as a HashSet on the value column. The method containsNode() returns true if the node is already in the graph and false if it is not. The problem is in the addNode() and addNodes() method. addNode() return true if the added node is not duplicated and false otherwise. For the addNodes(String[] nodeName) method, if one of the node in the array of nodes is duplicated, continue adding other nodes and also return false.
There is a lot of redundancy in my codes and I don't know how to shorten it. Especially the part in both addNode & addNodes method:
if (!this.containsNode(name)) {
table.put(name, new HashSet<String>());
I can't use addNode() to write addNodes(), because if I try to loop through the given node array, it will return as soon as it hits the first index, since addNode return type is boolean.
Moreover, I don't know how to return false afterwards in the addNodes() method,in case I found 1 duplicate node. So as you can see, I have to reloop the array again to search for duplicate nodes and decide which boolean to return. Do you guys have any idea in order to shorten this ? Thank you.
public class Graph {
private HashMap<String, HashSet<String>> table;
protected Graph() {
this.table = new HashMap<String, HashSet<String>>();
}
private boolean containsNode(String name) {
return table.containsKey(name);
}
public boolean addNode(String name) {
if (!this.containsNode(name)) {
table.put(name, new HashSet<String>());
return true;
}
return false;
}
public boolean addNodes(String[] names) {
for (int i = 0; i < names.length; i++) {
if (!this.containsNode(names[i])) {
table.put(names[i], new HashSet<String>());
}
else {
continue;
}
}
for (int i = 0; i < names.length; i++) {
if (!this.containsNode(names[i])) {
return false;
}
}
return true;
}
}
Upvotes: 0
Views: 107
Reputation: 1181
Your addNode()
provides a certain level of fail-safe. It guarantees an existing node will not be overwritten. If addNode()
provides this security, it is safe to employ addNode()
within addNodes()
without repeating the duplication check. addNode()
’s return will tell if a node exists or not. So I simplify addNodes()
as
public boolean addNodes(String[] names) {
// assume all nodes are new
boolean allnew = true;
for (int i = 0; i < names.length; i++) {
// if any node exists, allnew turns false
allnew = allnew && addNode(names[i]);
}
return allnew;
}
The whole class
import java.util.HashMap;
import java.util.HashSet;
public class Graph {
private HashMap<String, HashSet<String>> table;
protected Graph() {
this.table = new HashMap<String, HashSet<String>>();
}
private boolean containsNode(String name) {
return table.containsKey(name);
}
public boolean addNode(String name) {
if (!this.containsNode(name)) {
table.put(name, new HashSet<String>());
return true;
}
return false;
}
public boolean addNodes(String[] names) {
// assume all nodes are new
boolean allnew = true;
for (int i = 0; i < names.length; i++) {
// if any node exists, allnew turns false
allnew = allnew && addNode(names[i]);
}
return allnew;
}
@Override
public String toString() {
StringBuffer buff = new StringBuffer();
table.keySet().forEach(node -> {
buff.append(String.format("%s={%s}\n", node, String.join(",", table.get(node))));
});
return buff.toString();
}
}
The main
public static void main(String[] args) {
Graph graph = new Graph();
System.out.println("initialize graph...");
graph.addNode("A");
System.out.println("add node A, graph:");
System.out.println(graph);
graph.addNode("B");
System.out.println("add node B, graph:");
System.out.println(graph);
boolean bool = graph.addNodes(new String[] { "C", "D" });
System.out.println(String.format("add nodes [C, D], sucessful: %s, graph:", bool));
System.out.println(graph);
bool = graph.addNodes(new String[] { "E", "D" });
System.out.println(String.format("add nodes [E, D], sucessful: %s, graph:", bool));
System.out.println(graph);
}
Console output
initialize graph...
add node A, graph:
A={}
add node B, graph:
A={}
B={}
add nodes [C, D], sucessful: true, graph:
A={}
B={}
C={}
D={}
add nodes [E, D], sucessful: false, graph:
A={}
B={}
C={}
D={}
E={}
Upvotes: 0