Digraph

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Scanner;


public class Digraph {

    private int numVertices;
    private int numEdges;
    private Bag<Integer>[] adj; //adjacency lists
    
    //constructor - creates empty digraph with numVertices vertices
    public Digraph(int numVertices) {
        initializeEmptyDigraph(numVertices);
    }
    
    // create a graph from a file
    public Digraph(String pathToFile) {
        File f = new File(pathToFile);
        Scanner scanner;
        try {
            scanner = new Scanner(f);
            
            // read number of vertices
            int numVertices = Integer.parseInt(scanner.nextLine()); 
            initializeEmptyDigraph(numVertices);
            
            while (scanner.hasNextLine()) {     // read and add edges
                int v = scanner.nextInt();
                int w = scanner.nextInt();
                this.addEdge(v, w);
            }
        } 
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    private void initializeEmptyDigraph(int numVertices) {
        this.numVertices = numVertices;
        adj = (Bag<Integer>[]) new Bag[numVertices]; // <-- the necessary, ugly cast
        for (int v = 0; v < numVertices; v++) {
            adj[v] = new Bag<Integer>();
        }
    }
    
    // getters for number of vertices and edges
    public int numVertices() {
        return this.numVertices;
    }
    
    public int numEdges() {
        return this.numEdges;
    }
    
    // add a directed edge
    public void addEdge(int fromVertex, int toVertex) {
        adj[fromVertex].add(toVertex);
        numEdges++;
    }
    
    // iterator for vertices point from v
    public Iterable<Integer> adj(int v) {
        return adj[v];
    }
    
    public Digraph reverse() {
        Digraph reversedDigraph = new Digraph(this.numVertices);
        for (int v = 0; v < this.numVertices; v++) 
            for (int w : this.adj(v))          // for every w adjacent to v, add edge w->v
                reversedDigraph.addEdge(w, v);
        return reversedDigraph;
    }
    
    public String toString() {
        String s = "v | adj vertices\n";
        s += "--|-------------\n";
        for (int v = 0; v < adj.length; v++) {
            s += v + " -> ";
            for (Integer w : adj[v]) {
                s += w + " ";
            }
            s += "\n";
        }
        return s;
    }
    
    public static void main(String[] args) {
        Digraph dg = new Digraph(args[0]);
        System.out.println(dg);
        Digraph rdg = dg.reverse();
        System.out.println(rdg);
    }
}