I am inputting an adjacency list for a graph. There are three columns of data (vertex, destination, edge) separated by a single space. Here is my implementation so far:
FileStream in = new FileStream("input1.txt");
Scanner s = new Scanner(in);
String buffer;
String [] line = null;
while (s.hasNext())
{
buffer = s.nextLine();
line = buffer.split("\\s+");
g.add(line[0]);
System.out.println("Added vertex " + line[0] + ".");
g.addEdge(line[0], line[1], Integer.parseInt(line[2]));
System.out.println("Added edge from " + line[0] + " to " + line[1] + " with a weight of " + Integer.parseInt(line[2]) + ".");
}
System.out.println("Size of graph = " + g.size());
Here is the output:
Added vertex a.
Added edge from a to b with a weight of 9.
Exception in thread "main" java.lang.NullPointerException
at structure5.GraphListDirected.addEdge(GraphListDirected.java:93)
at Driver.main(Driver.java:28)
I was under the impression that
line = buffer.split("\\s+");
would return a 2 dimensional array of Strings to the variable line. It seemed to work the first time but not the second. Any thoughts?
I would also like some feedback on my implementation of this problem. Is there a better way?
Anything to help out a novice! 🙂
EDIT:
I tried this implementation earlier today and was unsuccessful. I did it again here:
FileStream in = new FileStream("input1.txt");
Scanner s = new Scanner(in).useDelimiter("\\s+");
while (s.hasNext())
{
Scanner line = new Scanner(s.nextLine());
String vertex = line.next();
String destination = line.next();
int weight = line.nextInt();
g.add(vertex);
System.out.println("Added vertex " + vertex + ".");
g.addEdge(vertex, destination, weight);
System.out.println("Added edge from " + vertex + " to " + destination + " with a weight of " + weight + ".");
}
System.out.println("Size of graph = " + g.size());
Output:
Added vertex a.
Exception in thread "main" java.lang.NullPointerException
at structure5.GraphListDirected.addEdge(GraphListDirected.java:93)
at Driver.main(Driver.java:22)
Edit2:
Here is the addEdge function. This is not my own implementation I am using it to save the time of feebly writing my own at this beginning stage…
package structure5;
import java.util.Iterator;
abstract public class GraphList<V,E> extends AbstractStructure<V> implements Graph<V,E>
{
protected Map<V,GraphListVertex<V,E>> dict; // label -> vertex
protected boolean directed; // is graph directed?
protected GraphList(boolean dir)
{
dict = new Hashtable<V,GraphListVertex<V,E>>();
directed = dir;
}
public void add(V label)
{
if (dict.containsKey(label)) return; // vertex exists
GraphListVertex<V,E> v = new GraphListVertex<V,E>(label);
dict.put(label,v);
}
abstract public void addEdge(V v1, V v2, E label);
}
Graph.java:
package structure5;
import java.util.Iterator;
public interface Graph<V,E> extends Structure<V>
{
public void add(V label);
public void addEdge(V vtx1, V vtx2, E label);
}
Note: I am leaving out the rest of the methods that don’t pertain to the program
Edit3:
Here is GraphListDirected.java
public class GraphListDirected<V,E> extends GraphList<V,E>
{
public GraphListDirected()
{
super(true);
}
public void addEdge(V vLabel1, V vLabel2, E label)
{
GraphListVertex<V,E> v1 = dict.get(vLabel1);
GraphListVertex<V,E> v2 = dict.get(vLabel2);
Edge<V,E> e = new Edge<V,E>(v1.label(), v2.label(), label, true); //Line 93
v1.addEdge(e);
}
String.splitreturns aString[], a one-dimensional array, never a two dimensional array. You can, of course, furthersplitaStringthat was the result of asplit(and so on).Having said that, since you’re already using
Scanner, you should never need to usesplitandInteger.parseIntetc. Just create anotherScannerto scans.nextLine().I’m not sure what caused the
NullPointerException, although we know from your output that at least one edge was successfully added.API links
Scanner(String source)Scannerthat produces values scanned from the specified string.On multiple
ScannerThe little A-ha!! moment here is the realization that just as you can
spliton the result of a previoussplit, you can create aScannerto scan strings returned from anotherScanner.The above snippet prints:
This is just a simple example, but you can see the value of this technique when each line is more complex, e.g. when it contains numbers and regex patterns.
On the
NullPointerExceptionYou need to
addboth the starting and ending vertices, because of the wayaddEdgeis implemented.This should fix the
NullPointerException.Hopefully the process of finding this bug has been educational: it took several revisions to the question to gather the relevant information, but finally the culprit of the error has been identified.