static <T extends Comparable<T>> T max(T a, T b) {
return a.compareTo(b) >= 0 ? a : b;
}
// ...
System.out.println(max(3, 7) + " " + max("pear", "apple") + " " + max("Zoo", "apple"));
Q8
Using the max method of the previous question, what happens with System.out.println(max(3, "x"));?
Q9
By convention, what do the type parameters in Map<K, V> and List<E> stand for?
Q10
Given List<? extends Number> nums = new ArrayList<Integer>();, which statement compiles?
Q11
Given List<? super Integer> sink = new ArrayList<Number>();, which statement does not compile?
Q12
A method average(... values) only reads numbers from a list and must accept a List<Integer>, a List<Double> and a List<Number>. Which parameter type is best?
Q13
With the method below and the lists List<Integer> ints, List<Number> nums, List<Object> objs, which call does not compile?
static <T> void copy(List<? super T> dst, List<? extends T> src) {
for (T t : src) dst.add(t);
}
Q14
What is printed?
static double sum(List<? extends Number> xs) {
double s = 0;
for (Number n : xs) s += n.doubleValue();
return s;
}
// ...
System.out.println(sum(Arrays.asList(1, 2.5, 3)));
Q15
What does this print?
System.out.println(new ArrayList<String>().getClass()
== new ArrayList<Integer>().getClass());
Q16
Which line compiles inside class Box<T> { ... }?
Q17
Inside static <T> boolean test(Object o) { return ... ; }, which expression compiles under Java 8?
Q18
Does this class compile?
class Printer {
void print(List<String> a) { System.out.println("strings"); }
void print(List<Integer> a) { System.out.println("integers"); }
}
Q19
What happens when this code runs?
List<String> s = new ArrayList<>();
List raw = s;
raw.add(42);
System.out.println("size " + s.size());
String x = s.get(0);
System.out.println("got " + x);
Q20
Which type-parameter declaration compiles?
Q21
What is printed?
class Pair<K, V> {
private final K key;
private final V value;
Pair(K key, V value) { this.key = key; this.value = value; }
K getKey() { return key; }
V getValue() { return value; }
Pair<V, K> swap() { return new Pair<>(value, key); }
}
// in main:
Pair<String, Integer> p = new Pair<>("a", 1);
System.out.println(p.swap().getKey() + 10);
System.out.println(p.getKey() + p.getValue() + 10);
Q22
What is printed?
List<Integer> list = new ArrayList<>(Arrays.asList(10, 1, 20, 1));
list.remove(1);
System.out.println(list);
list.remove(Integer.valueOf(1));
System.out.println(list);
Q23
Given static <T> T pick(T a, T b) { return b; }, which statement compiles?
Q24
In class SortedBox<T extends Comparable<T>> { private T item; ... }, what is the type of the field item after erasure (as seen through reflection at run time)?
Q25Short answer
Explain the PECS rule. Using the signature static <T> void copy(List<? super T> dst, List<? extends T> src), explain why src uses extends and dst uses super, and what would be lost if both parameters were declared List<T>.
Q26Short answer
What is type erasure? Give three restrictions that it imposes on generic code, with a one-line reason for each.
Q27Short answer
Arrays in Java are covariant (String[] is an Object[]) but generic types are invariant (List<String> is not a List<Object>). Write a two-line example that shows what would go wrong if List<String> were a subtype of List<Object>, and explain how arrays protect themselves instead.
Q28Short answer
What is a raw type? Why should you avoid raw types in new code, and what should you write instead when you really do not care about the element type?
Q29Programming
Write a static generic method countGreater that receives an array of any comparable type and a value x of the same type, and returns how many elements are strictly greater than x. For example, countGreater(new Integer[]{5, 1, 9, 5, 7}, 5) returns 2 and countGreater(new String[]{"kiwi", "apple", "pear"}, "fig") returns 2.
Q30Programming
Write two static methods that follow the PECS rule:
sumAll, which returns the sum (as a double) of any collection of numbers — it must accept a List<Integer>, a Set<Double> or a List<Number>;
fillWith, which adds the integers 1, 2, …, n to a list — it must accept a List<Integer>, a List<Number> or a List<Object>.