Google

May 6, 2014

Java Generics written test questions and answers



Q1. Which of the following are legal in the underline specified?

     ______________ = new ArrayList<Integer>();  // line 1

     numbers.add(5);    //line 2                               

a) List<? super Integer> numbers
b) List<? super Number> numbers
c) List<Object> numbers
d) List<? extends Integer> numbers
e) List<?> numbers
f) List<Integer> numbers


A1. a and f.

a) is legal because the rule for

<? super T> is

for List<T> to write (i.e. add) to the destination, and does not care if the destination also contain subclasses of T. In the above example T happens to be an Integer.

b) Line 1 is illegal because T is an Integer and not a Number as per the above rule.

c) Line 1 is illegal because the super class of List<T> is List<?> and not List<Object>. List<?> means the collection of the unknown.

d) Line 2 is illegal because  the rule for

<? extends T>  is

for List<? extends T> is for read only and you can't add to it. It does not care if the actual object retrieved is a sub type of T. In the above example, T happens to be an Integer.

e) Line 1 is illegal because you can't add anything to a list of unknown (i.e. List<?>)

f) is legal as T is Integer.


Note: Illegal means you get compile-time error. Java generics check happens only at compile-time.


Q2. Which of the following are legal in the underline specified?

    List<Integer> numbers = ______________________; //Line1
    numbers.add(5); 


a) new ArrayList<Integer>();
b) new ArrayList<?>();
c) new ArrayList<? super Integer>();
d) new ArrayList<? extends Integer>();
e) new ArrayList<>();
f) new ArrayList<Number>();
g) new ArrayList<Object>();


A2. a and e (only from Java 8, the empty diamond is allowed on instantiation.

b, c, and d are illegal on Line 1 because ? (i.e. the wild card) types cannot be instantiated.

f and g are illegal on Line 1 because T is an Integer, and List<Number> and List<Object> cannot be converted to List<Integer>



Q3. Can you use generics with Java arrays?
A3.  No. One of the reasons to favor a List over an Array is because  a List supports generics to provide compile time type-safety check.

Q4. What do you understand by the term type erasure?
A4:  Generics in Java is implemented using type erasure that happens at compile time. This means a List&ltNumber&gt becomes just a List at run-time. This was done to preserve backward compatibility.

Q5. Given the following Pair class that takes Generic data types

public class Pair<T, S> {
 
 public T first;
 public S second;

 public Pair(T a, S b) { 
  first = a;
  second = b;
 }
 
}


Which of the following statements compile without errors?

a) Pair<String,Color> colorName = new Pair<String,Color>("Red", Color.RED);
b) Pair<Double,Double> coordinates = new Pair<Double,Double>(17.3,42.8);
c) Pair<String,Double> keyValue = new Pair<String,Double>("PI", "22/7");
d) Pair<String,Double> lookUp = new Pair<>("right-angle", 90.0);
e) Pair<String,String, String> lookUp = new Pair<>("a", "b", "c");


A5.  a, b, and d (empty-diamond compiles from Java 8 on wards).

c) won't compile as "22/7" should be of type Double and not String. The constructor expects an object of type Double.  Actual error: The constructor Pair<String,Double>(String, String) is undefined

e) won't compile as it expects only two arguments and not three. Actual error: Incorrect number of arguments for type Pair<T,S>; it cannot be parameterized with arguments <String, String, String>


Q6. Given the following implementation to count the number of occurrences of a given item. The example below counts the occurrences of number 6, and returns 3 as the count.

public class OccrrencesTest {

 public static  int countOccurrences(Integer[] list, Integer itemToCount) {
  int count = 0;
  if (itemToCount == null) {
   for (Integer listItem : list)
    if (listItem == null)
     count++;
  } else {
   for (Integer listItem : list)
    if (itemToCount.equals(listItem))
     count++;
  }
  return count;
 }
 
 public static void main(String[] args) {
  Integer[] numbers = {5,6,6,5,7,8,6};
  System.out.println(countOccurrences(numbers, 6));
 }
}


How will you ensure that the  implementation works with other types like String, Color, Double, etc ?


A6. If you want to use the static method approach, you method needs to use the generic method type, for example <T> as shown below. Note that the generic type is also used in the static method signature before the return type int.

public class OccrrencesTest {

 public static <T>  int countOccurrences(T[] list, T itemToCount) {
  int count = 0;
  if (itemToCount == null) {
   for (T listItem : list)
    if (listItem == null)
     count++;
  } else {
   for (T listItem : list)
    if (itemToCount.equals(listItem))
     count++;
  }
  return count;
 }
 
 public static void main(String[] args) {
  Integer[] numbers = {5,6,6,5,7,8,6};
  System.out.println(countOccurrences(numbers, 6));
 }
}




if you want to use instance method approach

public class OccrrencesTest<T> {

 public int countOccurrences(T[] list, T itemToCount) {
  int count = 0;
  if (itemToCount == null) {
   for (T listItem : list)
    if (listItem == null)
     count++;
  } else {
   for (T listItem : list)
    if (itemToCount.equals(listItem))
     count++;
  }
  return count;
 }
 
 public static void main(String[] args) {
  Integer[] numbers = {5,6,6,5,7,8,6};
  System.out.println(new OccrrencesTest<Integer>().countOccurrences(numbers, 6));
 }
}


In both examples, the type of T is inferred at compile-time. Type inference is a Java compiler's ability to look at each method invocation and corresponding declaration to determine the type argument (or arguments) that make the invocation applicable.

You can now use other types like Color as shown below

Color[] numbers = {Color.RED, Color.blue};
System.out.println(new OccrrencesTest<Color>().countOccurrences(numbers, Color.RED));


Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home