Professional Documents
Culture Documents
Fraser 1908
3 Java Puzzlers Unbugged
Fraser 1908
4 Java Puzzlers Unbugged
Fraser 1908
5 Java Puzzlers Unbugged
Logvinenko 1999
6 Java Puzzlers Unbugged
Logvinenko 1999
7 Java Puzzlers Unbugged
Logvinenko 1999
8 Java Puzzlers Unbugged
Kitaoka 1998
9 Java Puzzlers Unbugged
Kitaoka 1998
10 Java Puzzlers Unbugged
Kitaoka 1998
11 Java Puzzlers Unbugged
12
1. Glommer Pile
public class Glommer<T> { String glom(Collection<?> objs) { String result = ""; for (Object o : objs) result += o; return result; } int glom(List<Integer> ints) { int result = 0; for (int i : ints) result += i; return result; } public static void main(String args[]) { List<String> strings = Arrays.asList("1", "2", "3"); System.out.println(new Glommer().glom(strings)); }
}
13
(a) 6 (b) 123 (c) Throws exception (d) None of the above
}
14
public static void main(String args[]) { List<String> strings = Arrays.asList("1", "2", "3"); System.out.println(new Glommer().glom(strings)); }
15
Another Look
public class Glommer<T> { String glom(Collection<?> objs) { String result = ""; for (Object o : objs) result += o; return result; } int glom(List<Integer> ints) { int result = 0; for (int i : ints) result += i; return result; } public static void main(String args[]) { List<String> strings = Arrays.asList("1", "2", "3"); System.out.println(new Glommer().glom(strings)); }
}
16
And hopefully:
javac -Xlint:unchecked Glommer.java Glommer.java:20: warning: [unchecked] unchecked call to glom(java.util.List<java.lang.Integer>) as a member of the raw type Glommer System.out.println(new Glommer().glom(strings)); ^
17
}
18
}
19
}
20
The Moral
Do not use raw types Raw types lose all type information
Can compromise overload resolution
21
2. Time for a Change If you pay $2.00 for a gasket that costs $1.10, how much change do you get?
public class Change { public static void main(String args[]) { System.out.println(2.00 - 1.10); } }
22
2. A Change is Gonna Come If you pay $2.00 for a gasket that costs $1.10, how much change do you get?
import java.math.BigDecimal; public class Change { public static void main(String args[]) { BigDecimal payment = new BigDecimal(2.00); BigDecimal cost = new BigDecimal(1.10); System.out.println(payment.subtract(cost)); } }
23
24
(a) .9 (b) .90 (c) 0.8999999999999999 (d) None of the above: 0.89999999999999991118215802998 7476766109466552734375
We used the wrong BigDecimal constructor
25
Another Look
public BigDecimal(double val) Translates a double into a BigDecimal which is the exact decimal representation of the double's binary floating-point value.
import java.math.BigDecimal; public class Change { public static void main(String args[]) { BigDecimal payment = new BigDecimal(2.00); BigDecimal cost = new BigDecimal(1.10); System.out.println(payment.subtract(cost)); } }
26
import java.math.BigDecimal; public class Change { public static void main(String args[]) { BigDecimal payment = new BigDecimal("2.00"); BigDecimal cost = new BigDecimal("1.10"); System.out.println(payment.subtract(cost)); } }
27
The Moral
28
abstract class Sink<T> { abstract void add(T... elements); void addUnlessNull(T... elements) { for (T element : elements) if (element != null) add(element); } } public class StringSink extends Sink<String> { final List<String> list = new ArrayList<String>(); void add(String... elements) { list.addAll(Arrays.asList(elements)); } @Override public String toString() { return list.toString(); } public static void main(String[] args) { Sink<String> ss = new StringSink(); ss.addUnlessNull("null", null); System.out.println(ss); } }
30 Java Puzzlers Unbugged
(a) StringSink@19821f (b) [null] (c) [null, null] (d) None of the above
31
Another Look
And hopefully:
javac -Xlint:unchecked StringSink.java StringSink.java:7: warning: [unchecked] unchecked generic array creation of type T[] for varargs parameter if (element != null) add(element); ^
34
The Moral
36
37
(a) 99 (b) 100 (c) Throws an exception (d) None of the above
38
39
40
The regex "(aa|aab)+" matches exactly the same strings as "(aa|aab?)+" but doesnt exhibit catastrophic backtracking
41
Moral
42
5. Size Matters
public class Size { private enum Sex { MALE, FEMALE } public static void main(String[] args) { printSize(new HashMap<Sex, Sex>()); printSize(new EnumMap<Sex, Sex>(Sex.class)); } private static void printSize(Map<Sex, Sex> map) { map.put(Sex.MALE, Sex.FEMALE); map.put(Sex.FEMALE, Sex.MALE); map.put(Sex.MALE, Sex.MALE); map.put(Sex.FEMALE, Sex.FEMALE); Set<Map.Entry<Sex, Sex>> set = new HashSet<Map.Entry<Sex, Sex>>(map.entrySet()); System.out.println(set.size()); }
public static void main(String[] args) { printSize(new HashMap<Sex, Sex>()); printSize(new EnumMap<Sex, Sex>(Sex.class)); } private static void printSize(Map<Sex, Sex> map) { map.put(Sex.MALE, Sex.FEMALE); map.put(Sex.FEMALE, Sex.MALE); map.put(Sex.MALE, Sex.MALE); map.put(Sex.FEMALE, Sex.FEMALE); Set<Map.Entry<Sex, Sex>> set = new HashSet<Map.Entry<Sex, Sex>>(map.entrySet()); System.out.println(set.size()); }
44
Enumerating over entry sets works better for Some Map implementations than others
45 Java Puzzlers Unbugged
Another Look
public class Size { private enum Sex { MALE, FEMALE } public static void main(String[] args) { printSize(new HashMap<Sex, Sex>()); printSize(new EnumMap<Sex, Sex>(Sex.class)); } private static void printSize(Map<Sex, Sex> map) { map.put(Sex.MALE, Sex.FEMALE); map.put(Sex.FEMALE, Sex.MALE); map.put(Sex.MALE, Sex.MALE); map.put(Sex.FEMALE, Sex.FEMALE); Set<Map.Entry<Sex, Sex>> set = new HashSet<Map.Entry<Sex, Sex>>(map.entrySet()); System.out.println(set.size()); }
47
}
48
Moral
49
50
52
Another Look
public class LongDivision { private static final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000; private static final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000; // >> Integer.MAX_VALUE public static void main(String[] args) { System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY); } }
53
54
The Moral
for overflowits a silent killer Just because variable can hold result doesnt mean computation wont overflow
type
55
56
(a) 17777 44444 (b) 17777 43878 (c) 66666 44444 (d) 66666 43878
57 Java Puzzlers Unbugged
Program doesnt say what you think it does! Also, leading zeros can cause trouble.
58
Another Look
public class Elementary { public static void main(String[] args) { System.out.println( 2345 + 5432 ); System.out.println(01234 + 43210); } }
60
61
The Moral
62
Conclusion
Keep programs clear and simple If you arent sure what a program does,
it probably doesnt do what you want
63
64
Java Puzzlers:
Scraping the Bottom of the Barrel
65