Implications for Exception Handling

When an exception is thrown in a try block, it is matched against the parameter of each catch block that is associated with the try block. This test is similar to the instance test, requiring reifiable types. The following restrictions apply:

• The type of the parameter of a catch block must be a reifiable type and it must also be a subtype of Throwable.

• A generic type cannot extend the Throwable class.

• A parameterized type cannot be specified in a throws clause.

The following example illustrates the three restrictions:

// (1) A generic class can not extend Exception:
class MyGenericException<T> extends Exception { }         // 
Compile-time error!

public class ExceptionErrors {

  // (2) Cannot specify parameterized types in throws clause:
  public static void main(String[] args)
                     throws MyGenericException<String> { // 
Compile-time error!
    try {

      throw new MyGenericException<String>();
    // (3) Cannot use parameterized type in catch block:
    } catch (MyGenericException<String> e) {             //
 Compile-time error!
      e.printStackTrace();
    }
  }
}

However, type parameters are allowed in the throws clause, as Example 14.16 shows. In the declaration of the MyActionListener interface, the method doAction() can throw an exception of type E. The interface is implemented by the class FileAction, that provides the actual type parameter (FileNotFoundException) and implements the doAction() method with this actual type parameter. All is above board, as only reifiable types are used for exception handling in the class FileAction.

Example 14.16 Type Parameter in throws Clause

public interface MyActionListener<E extends Exception> {
  public void doAction() throws E;       // Type parameter in throws clause
}
_____________________________________________________
import java.io.FileNotFoundException;

public class FileAction implements MyActionListener
<FileNotFoundException> {

  public void doAction() throws FileNotFoundException {
     throw new FileNotFoundException("Does not exist");
  }
  public static void main(String[] args) {
    FileAction fileAction = new FileAction();
    try {
      fileAction.doAction();
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    }
  }
}

Implications for Nested Classes

All nested classes and interfaces can be declared as generic types except anonymous classes. Anonymous classes do not have a name, and a class name is required for declaring a generic class and specifying its type parameters. An anonymous class can be a parameterized type, where the actual type parameters are supplied in the anonymous class expression.

class GenericTLC<A> {             // (1) Top level class

  static class SMC<B> {/*...*/}   // (2) Static member class

  interface SMI<C> {/*...*/}      // (3) Static member interface

  class NSMC<D> {/*...*/}         // (4) Non-static member (inner) class

  void nsm() {
    class NSLC<E> {/*...*/}       // (5) Local (inner) 
class in non-static context
  }

  static void sm() {
    class SLC<F> {/*...*/}        // (6) Local (inner) class in static context
  }

  // Anonymous classes as parameterized types:
  SMC<Integer> nsf = new SMC<Integer>() {      // (7) In non-static context
    /*...*/
  };
  static SMI<String> sf = new SMI<String>() {  // (8) In static context
    /*...*/
  };
}

The type parameter names of a generic nested class can hide type parameter names in the enclosing context (see (2) in Example 14.17). Only a non-static nested class can use the type parameters in its enclosing context, as type parameters cannot be referenced in a static context.

Example 14.17 also illustrates instantiating generic nested classes. As a static member class does not have an outer instance, only its simple name is parameterized, and not the enclosing types, as shown by the code at (6). As a non-static member class requires an outer instance, any generic enclosing types must also be parameterized and instantiated, as shown by the code at (7). See Section 8.3, p. 360, for the syntax used in instantiating nested classes.

Example 14.17 Generic Nested Classes

public class ListPool<T> {        // (1) Top level class

  static class MyLinkedList<T> {  // (2) Hiding type 
parameter in enclosing context
    T t;                           // T refers to (2)
  }

  class Node<E> {                  // (4) Non-static member (inner) class
    T t;                           // T refers to (1)
    E e;
  }

  public static void main(String[] args) {
    // (5) Instantiating a generic top-level class:
    ListPool<String> lp = new ListPool<String>();

    // (6) Instantiating a generic static member class:
    ListPool.
MyLinkedList<String> list = new ListPool.MyLinkedList<String>();

    // (7) Instantiating a generic non-static member class:
    ListPool<String>.Node<Integer> node1 = lp.new Node
<Integer>();
    ListPool<String>.Node<Double> node2 = lp.new Node
<Double>();
    ListPool<Integer>.Node<String> node3
                      = new ListPool<Integer>().new Node<String>();
  }
}

Other Implications

Enums

Because of the way enum types are implemented using the java.lang.Enum class, we cannot declare a generic enum type:

enum COIN_TOSS<C> { HEAD, TAIL; }                  // Compile-time error!

An enum type can implement a parameterized interface, just like a non-generic class can. The enum type TRIPLE_JUMP implements the interface Comparator<TRIPLE_JUMP>:

enum TRIPLE_JUMP implements Comparator<TRIPLE_JUMP> {
  HOP, STEP, JUMP;

  public int compare(TRIPLE_JUMP a1, TRIPLE_JUMP a2) {
    return a1.compareTo(a2);
  }
}

Class Literals

Objects of the class Class<T> represent classes and interfaces at runtime, i.e., an instance of the Class<T> represents the type T. A class literal expression can only use reifiable types as type parameters, as there is only one class object.

   Node<Integer> intNode = new Node<Integer>(2008, null);
   Class<Node> class0 = Node<Integer>.class;  // Compile-time error!
   Class<Node> class1 = Node.class;           // OK

The getClass() method of the Object class also returns a Class object. The actual result type of this object is Class<? extends |T|> where |T| is the erasure of the static type of the expression on which the getClass() method is called. The following code shows that all invocations of the generic type Node<T> are represented by a single class literal:

   Node<String> strNode = new Node<String>("Hi", null);
   Class<?> class2 = strNode.getClass();
   Class<?> class3 = intNode.getClass();
   assert class1 == class2;
   assert class2 == class3;

Review Questions

Review Questions

14.18 Which statements can be inserted at (1) without the compiler reporting any errors?

public class RQ100_05 {
  public static void main(String[] args) {
    List<?> lst = new ArrayList<String>();
    // (1) INSERT HERE
  }
}

Select the two correct answers.

(a) lst.add(null);

(b) lst.add("OK");

(c) lst.add(2007);

(d) String v1 = lst.get(0);

(e) Object v2 = lst.get(0);

14.19 What will the program print when compiled and run?

public class RQ100_00 {
  public static void main(String[] args) {
    List<String> lst1 = new ArrayList<String>();
    List<Integer> lst2 = new ArrayList<Integer>();
    List<List<Integer>> lst3 = new ArrayList<List<Integer>>();
    System.out.print(lst1.getClass() + " ");
    System.out.print(lst2.getClass() + " ");
    System.out.println(lst3.getClass());
  }
}

Select the one correct answer.

(a) class java.util.ArrayList<String> class java.util.ArrayList
<Integer> class java.util.ArrayList<List<Integer>>

(b) class java.util.ArrayList class java.util.ArrayList class
java.util.ArrayList

(c) class java.util.List class java.util.List class java.util.List

(d) class java.util.List<String> class java.util.List
<Integer> classjava.util.List<List<Integer>>

(e) The program will not compile.

(f) The program compiles, but throws an exception when run.

14.20 Which declarations can be inserted at (1) without the compiler reporting any errors?

public class RQ100_01 {
  public static void main(String[] args) {
  //  (1) INSERT DECLARATIONS HERE
  }

  public static <E extends Number> List<E> justDoIt(List<? super E> nums) {

    return null;
  }
}

Select the three correct answers.

(a) ArrayList<Integer> inParam = new ArrayList<Integer>();
ArrayList<Integer> returnValue = justDoIt(inParam);

(b) ArrayList<Integer> inParam = new ArrayList<Integer>();
List<Integer> returnValue = justDoIt(inParam);

(c) ArrayList<Integer> inParam = new ArrayList<Integer>();
List<Number> returnValue = justDoIt(inParam);

(d) List<Number> inParam = new ArrayList<Number>();
ArrayList<Integer> returnValue = justDoIt(inParam);

(e) List<Number> inParam = new ArrayList<Number>();
List<Number> returnValue = justDoIt(inParam);

(f) List<Integer> inParam = new ArrayList<Integer>();
List<Integer> returnValue = justDoIt(inParam);

14.21 The class java.lang.String implements the interface java.lang.CharSequence. Given the following code:

public class RQ100_02 {
  public static void main(String[] args) {
    List<String> lst = Arrays.asList("Java", "only", "promotes", "fun");
    Collection<String> resultList = delete4LetterWords(lst);
  }

  // (1) INSERT METHOD HEADER HERE
  {
    Collection<E> permittedWords = new ArrayList<E>();
    for (E word : words) {
      if (word.length() != 4) permittedWords.add(word);
    }
    return permittedWords;
  }
}

Which method header can be inserted at (1) so that the program compiles and runs without errors?

Select the one correct answer.

(a) static <E extends CharSequence> Collection<? extends 
CharSequence>delete4LetterWords(Collection<E> words)

(b) static <E extends CharSequence> List<E>
delete4LetterWords(Collection<E> words)

(c) static <E extends CharSequence> Collection<E>
delete4LetterWords(Collection<? extends CharSequence> words)

(d) static <E extends CharSequence> List<E>
delete4LetterWords(Collection<? extends CharSequence> words)

(e) static <E extends CharSequence> Collection<E>
delete4LetterWords(Collection<E> words)

(f) public <E super CharSequence> Collection<E>
delete4LetterWords(Collection<E> words)

14.22 Which declaration can be inserted at (1) so that the program compiles and runs without errors?

public class RQ100_06 {
  public static void main(String[] args) {
    //  (1) INSERT DECLARATION HERE
    for (int i = 0; i <= 5; i++) {
      List<Integer> row = new ArrayList<Integer>();
      for (int j = 0; j <= i; j++)
        row.add(i * j);
      ds.add(row);
    }
    for (List<Integer> row : ds)
      System.out.println(row);
  }
}

Select the one correct answer.

(a) List<List<Integer>> ds = new List<List<Integer>>();

(b) List<ArrayList<Integer>> ds = new ArrayList<ArrayList<Integer>>();

(c) List<List<Integer>> ds = new ArrayList<List<Integer>>();

(d) ArrayList<ArrayList<Integer>> ds = new ArrayList<ArrayList<Integer>>();

(e) List<List<Integer>> ds = new ArrayList<ArrayList<Integer>>();

(f) List<List, Integer> ds = new List<List, Integer>();

(g) List<List, Integer> ds = new ArrayList<List, Integer>();

(h) List<List, Integer> ds = new ArrayList<ArrayList, Integer>();

14.23 Which method declarations cannot be inserted independently at (2) to overload the method at (1)?

public class RQ_Overloading {

  static <T> void overloadMe(List<T> s1, List<T> s2) { } // (1)
  // (2) INSERT DECLARATION HERE.
}

Select the two correct answers.

(a) static <T> void overloadMe(Collection<T> s1, List<T> s2) { }

(b) static <T> void overloadMe(List<T> s1, List<? extends T> s2) { }

(c) static <T> void overloadMe(List<T> s1, Collection<? super T> s2) { }

(d) static <T> void overloadMe(Collection<T> s1, Collection<? super T> s2) { }

(e) static <T> void overloadMe(Collection<T> s1, List<? super T> s2) { }

(f) static <T> void overloadMe(List<? extends T> s1, List<? super T> s2) { }

14.24 Which declarations can be inserted at (1) so that the program compiles and runs without errors?

public class RQ100_07 {
  public static void main(String[] args) {
    // (1) INSERT DECLARATION HERE
    appendAndPrint(lst, "hello");
  }

  static <T> void appendAndPrint(Collection<T> ds, T t) {
    ds.add(t);
    System.out.println(ds);
  }
}

Select the two correct answers.

(a) List<?> lst = new LinkedList<Object>();

(b) List<? extends Object> lst = new LinkedList<Object>();

(c) List<? super Object> lst = new LinkedList<Object>();

(d) List<Object> lst = new LinkedList<Object>();

14.25 Which method declaration can be inserted at (1) so that the program compiles without warnings?

public class RQ100_87 {
  public static void main(String[] args) {
    List raw = new ArrayList();
    raw.add("2007");
    raw.add(2008);
    raw.add("2009");
    justDoIt(raw);
  }
  // (1) INSERT METHOD DECLARATION HERE.
}

Select the one correct answer.

(a) static void justDoIt(List<Integer> lst) { }

(b) static void justDoIt(List<?> lst) { }

(c) static <T> void justDoIt(List<T> lst) { }

(d) None of the above.

14.26 Which method calls can be inserted at (1) so that the program compiles without warnings?

public class GenParam {
  public static void main(String[] args) {
    List<Number> numList = new ArrayList<Number>();
    List<Integer> intList = new ArrayList<Integer>();
    // (1) INSERT CODE HERE
  }

  static <T> void move(List<? extends T> lst1, List<? super T> lst2) { }
}

Select the three correct answers.

(a) GenParam.move(numList, intList);

(b) GenParam.<Number>move(numList, intList);

(c) GenParam.<Integer>move(numList, intList);

(d) GenParam.move(intList, numList);

(e) GenParam.<Number>move(intList, numList);

(f) GenParam.<Integer>move(intList, numList);

14.27 Which statement is true about the following code?

public class RQ100_86 {

  static void print1(List<String> lst) {     // (1)
    for(String element : lst) {
      System.out.print(element + " ");
    }
  }

  static void print2(List<String> lst) {     // (2)
    for(Object element : lst) {
      System.out.print(element + " ");
    }
  }

  static void print3(List<?> lst) {          // (3)
    for(Object element : lst) {
      System.out.print(element + " ");
    }
  }

  static <T> void print4(List<T> lst) {      // (4)
    for(Object element : lst) {
      System.out.print(element + " ");
    }
  }

  static <T> void print5(List<T> lst) {      // (5)
    for(T element : lst) {
      System.out.print(element + " ");
    }
  }
}

Select the one correct answer.

(a) The formal type parameter specification for the methods in (1), (2), and (3) is missing.

(b) The generic methods in (4) and (5) should be declared in a generic class.

(c) The element type Object for the local variable element in the for(:) loop header of the method in (3) is inconsistent with the element type of the list.

(d) The element type Object for the local variable element in the for(:) loop header of the method in (4) is inconsistent with the element type of the list.

(e) The program will compile without warnings.

(f) None of the above.

14.28 Which statements are true about the following code?

class MyClass<V> {
      MyClass()        {System.out.println(this);}           // (1)
      MyClass(V v)     {System.out.println(v);}              // (2)
  <T> MyClass(T t)     {System.out.println(t);}              // (3)
  <T> MyClass(T t, V v){System.out.println(t + ", " + v);}   // (4)
}

Select the two correct answers.

(a) The class attempts to declare four constructors.

(b) Only one of the two constructors in (2) and (3) can be declared in the class.

(c) A generic class cannot declare generic constructors.

(d) The compiler reports an error in (3), since the type parameter V is not used.

(e) The class compiles without problems.

14.29 Which declaration statement is not valid in the code below?

class AClass<V> {
      AClass()         {System.out.println(this);}               // (1)
  <T> AClass(T t)      {System.out.println(t);}                  // (2)
  <T> AClass(T t, V v) {System.out.println(t + ", " + v);}       // (3)
}

Select the one correct answer.

(a) AClass<String> ref1 = new AClass<String>();

(b) AClass<String> ref2 = new AClass<String>("one");

(c) AClass<String> ref3 = new AClass<String>(2007);

(d) AClass<String> ref4 = new <Integer>AClass<String>(2007);

(e) AClass<String> ref5 = new <String>AClass<String>("one");

(f) AClass<String> ref6 = new AClass<String>(2007, "one");

(g) AClass<String> ref7 = new <Integer>AClass<String>(2007, "one");

(h) AClass<String> ref8 = new <Integer>AClass<String>("one", 2007);

14.30 Which statements are true about the following code?

class SupX {
  public void set(Collection<?> c) {/*...*/} // (1)
}
class SubX extends SupX {
  public void set(List<?> l) {/*...*/}       // (2)
  public void set(Collection c) {/*...*/}    // (3)
}
//------------------------------------------
class SupY {
  public void set(Collection c) {/*...*/}    // (4)
}

class SubY extends SupY {
  public void set(Collection<?> c) {/*...*/} // (5)
}

Select the three correct answers.

(a) The method at (2) overloads the method at (1).

(b) The method at (2) overrides the method at (1).

(c) The method at (2) results in a compile-time error.

(d) The method at (3) overloads the method at (1).

(e) The method at (3) overrides the method at (1).

(f) The method at (3) results in a compile-time error.

(g) The method at (5) overloads the method at (4).

(h) The method at (5) overrides the method at (4).

(i) The method at (5) results in a compile-time error.

14.31 Which statements are true about the following code?

class SupC<T> {
  public void set(T t) {/*...*/}       // (1)
  public T get() {return null;}        // (2)
}

class SubC1<M,N> extends SupC<M> {
  public void set(N n) {/*...*/}       // (3)
  public N get() {return null;}        // (4)
}

class SubC2<M,N extends M> extends SupC<M> {
  public void set(N n) {/*...*/}       // (5)
  public N get() {return null;}        // (6)
}

Select the four correct answers.

(a) The method at (3) overloads the method at (1).

(b) The method at (3) overrides the method at (1).

(c) The method at (3) results in a compile-time error.

(d) The method at (4) overloads the method at (2).

(e) The method at (4) overrides the method at (2).

(f) The method at (4) results in a compile-time error.

(g) The method at (5) overloads the method at (1).

(h) The method at (5) overrides the method at (1).

(i) The method at (5) results in a compile-time error.

(j) The method at (6) overloads the method at (2).

(k) The method at (6) overrides the method at (2).

(l) The method at (6) results in a compile-time error.

14.32 Which types cannot be declared as generic types?

Select the three correct answers.

(a) Enum types

(b) Static member classes

(c) Any subclass of Throwable, i.e., exception classes

(d) Nested interfaces

(e) Anonymous classes

(f) Non-static member classes

(g) Local classes

14.33 What will be printed when the program is compiled and run?

class Tantrum<E extends Exception> {
  public void throwOne(E e) throws E {
    throw e;
  }
}

class TantrumException extends Exception {
  TantrumException(String str) {
    super(str);
  }
}

public class TakeException {
  public static void main(String[] args) {
    Tantrum<TantrumException> tantrum = new Tantrum<TantrumException>();
    try {
      tantrum.throwOne(new TantrumException("Tantrum thrown."));
    } catch 
(TantrumException te) {
      System.out.println(te.getMessage());
    }
  }
}

Select the one correct answer.

(a) The class Tantrum will not compile.

(b) The class TakeException will not compile.

(c) The program will compile, print "Tantrum thrown.", and terminate normally when run.

(d) The program will compile and will throw an exception and abort the execution when run.

14.34 What will be printed when the program is compiled and run?

public class CastAway {
  public static void main(String[] args) {
    Object obj = new ArrayList<Integer>();          // (1)
    List<?>       list1 = (List<?>) obj;            // (2)
    List<?>       list2 = (List) obj;               // (3)
    List          list3 = (List<?>) obj;            // (4)
    List<Integer> list4 = (List) obj;               // (5)
    List<Integer> list5 = (List<Integer>) obj;      // (6)
  }
}

Select the one correct answer.

(a) The program will not compile.

(b) The program will compile without any unchecked warnings. It will run with no output and terminate normally.

(c) The program will compile without any unchecked warnings. When run, it will throw an exception.

(d) The program will compile, but issue unchecked warnings. It will run with no output and terminate normally.

(e) The program will compile, but issue unchecked warnings. When run, it will throw an exception.

14.35 What will be printed when the program is compiled and run?

public class InstanceTest2 {
  public static void main(String[] args) {
    List<Integer> intList = new ArrayList<Integer>();
    Set<Double> doubleSet = new HashSet<Double>();
    List<?>          list = intList;
    Set<?>            set = doubleSet;

    scuddle(intList);
    scuddle(doubleSet);
    scuddle(list);
    scuddle(set);
  }

  private static void scuddle(Collection<?> col) {
    if (col instanceof List<?>) {
      System.out.println("I am a list.");
    } else if (col instanceof Set<?>) {
      System.out.println("I am a set.");
    }
  }
}

Select the one correct answer.

(a) The method scuddle() will not compile.

(b) The method main() will not compile.

(c) The program will compile, but issue an unchecked warning in method scuddle(). It will run and terminate normally with the following output:

I am a list.
I am a set.
I am a list.
I am a set.

(d) The program will compile, but issue an unchecked warning in the method main(). When run, it will throw an exception.

(e) The program will compile without any unchecked warnings. It will run and terminate normally, with the following output:

I am a list.
I am a set.
I am a list.
I am a set.

(f) The program will compile without any unchecked warnings. It will run and terminate normally, with the following output:

I am a list.
I am a set.

(g) None of the above.

14.36 Which statements will compile without errors and unchecked warnings when inserted at (1)?

public class Restrictions<T> {
  public void test() {
    // (1) INSERT ASSIGNMENT HERE.
  }
}

Select the four correct answers.

(a) T ref = new T();

(b) T[] arrayRef = new T[10];

(c) List<T>[] arrayOfLists0 = { new List<T>(), new List<T>() };

(d) List<T>[] arrayOfLists1 = new List<T>[10];

(e) List<?>[] arrayOfLists2 = new List<?>[10];

(f) List [] arrayOfLists3 = new List<?>[10];

(g) List<?>[] arrayOfLists4 = new List[10];

(h) List [] arrayOfLists5 = new List[10];

(i) List<String>[] arrayOfLists6 = new List[10];

14.37 What will be printed when the program is compiled and run?

public class GenArrays {
  public static <E> E[] copy(E[] srcArray) {
    E[] destArray = (E[]) new Object[srcArray.length];
    int i = 0;
    for (E element : srcArray) {
      destArray[i++] = element;
    }
    return destArray;
  }

  public static void main(String[] args) {
    String[] sa = {"9", "1", "1" };
    String[] da = GenArrays.copy(sa);
    System.out.println(da[0]);
  }
}

Select the one correct answer.

(a) The program will not compile.

(b) The program will compile, but issue an unchecked warning. When run, it will print "9".

(c) The program will compile, but issue an unchecked warning. When run, it will throw an exception.

(d) The program will compile without any unchecked warnings. When run, it will print "9".

(e) The program will compile without any unchecked warnings. When run, it will throw an exception.

14.38 What is the result of compiling and running the following program?

import java.util.Arrays;
import java.util.List;

public class GenVarArgs {
  public static <T> void doIt(List<T>... aols) {           // (1)
    for(int i = 0; i < aols.length; i++) {
      System.out.print(aols[i] + " ");
    }
  }

  public static void main(String... args) {                // (2)
    List<String> ls1 = Arrays.asList("one", "two");
    List<String> ls2 = Arrays.asList("three", "four");
    List<String>[] aols = new List[] {ls1, ls2};           // (3)
    doIt(aols);                                            // (4)
  }
}

Select the one correct answer.

(a) The program does not compile because of errors in (1).

(b) The program does not compile because of errors in (2).

(c) The program does not compile because of errors in (3).

(d) The program does not compile because of errors in (4).

(e) The program compiles and prints: [one, two] [three, four]

Chapter Summary

Chapter Summary

The following information was included in this chapter:

• how generic types, parameterized types, and raw types are related

• declaring generic types (classes and interfaces) and parameterized types

• extending generic types

• mixing generic code and legacy code

• the significance of unchecked warnings on type-safety

• understanding subtype relationships for wildcards

• understanding type hierarchy for wildcard parameterized types

• understanding widening and narrowing reference conversions in type hierarchy of wildcard parameterized types

• understanding restrictions on set and get operations when using references of wildcard parameterized types

• using bounded type parameters

• how to implement a generic class that is also Iterable

• understanding wildcard capture

• programming with wildcard parameterized types

• discussion of type erasure

• how overloading and overriding work with generics

• what reifiable types are and their role in generics

• understanding the limitations and restrictions that generics place on instance tests, casting, arrays, varargs, and exception handling

Programming Exercises

Programming Exercises

14.1 Write the generic method toMultiMap() that creates a multimap from a given map, as explained on page 702.

14.2 Write the generic method findVerticesOnPath() of the GraphTraversal class shown below. The method finds all the vertices on a path from a start vertex in a directed graph. (See also the explanation to the method declaration at (17) on page 702). The method uses the stack implementation MyStack<E> from Example 14.7, p. 695.

import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

public class GraphTraversal {

  public static void main(String[] args) {
    // (1) Given a directed graph with five vertices:
    Integer[][] neighbors = {
        {1, 3},  // Vertex 0
        {2},     // Vertex 1
        {4},     // Vertex 2
        {1, 2},  // Vertex 3
        {}       // Vertex 4
    };
    Map<Integer, Collection<Integer>> graph
                                    = new HashMap
<Integer, Collection<Integer>>();
    for (int i = 0; i < neighbors.length; i++) {
      graph.put(i, Arrays.asList(neighbors[i]));
    }

    // (2) Get start vertex.
    int startVertex;
    try {
      startVertex = Integer.parseInt(args[0]);
    } catch (ArrayIndexOutOfBoundsException ive) {

      System.out.println("Usage: java GraphTraversal [0-4]");
      return;
    } catch (NumberFormatException nfe) {
      System.out.println("Usage: java GraphTraversal [0-4]");
      return;
    }

    Set<Integer> visitedSet = GraphTraversal.findVerticesOnPath(graph,
                          startVertex);
    System.out.print("Vertex " + startVertex + " is connected to " + visitedSet);
  }

  /**
   * Finds the vertices on a path from a given vertex in a 
directed graph.
   * In the map, the key is a vertex, and the value is the 
collection
   * containing its neighbours.
   */
  public static <N> Set<N> findVerticesOnPath(Map<N,Collection<N>> graph,
                                              N startVertex) {
    // Implement the body of the method.
    // Uses the generic class MyStack from Example 14.7.
  }
}

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.110.103