1. Introduction - what this is about
Puzzles in java are those situations where the code is broken and
you are tricked by some API or the language itself.
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
2. Introduction - what this is about
Puzzles in java are those situations where the code is broken and
you are tricked by some API or the language itself.
Those were started mostly by Joch Bloch and there even a
book(some of the examples are taken from there)
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
3. Introduction - what this is about
Puzzles in java are those situations where the code is broken and
you are tricked by some API or the language itself.
Those were started mostly by Joch Bloch and there even a
book(some of the examples are taken from there)
Want it to be interactive
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
4. Awards as I think you will be lazy
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
5. SplittingSizes
public class RegexSplit {
public static void main(String[] args) {
String[] nothing = "".split(":");
String[] bunchOfNothing = ":".split(":");
System.out.printf("%d|%d%n", nothing.length,
bunchOfNothing.length);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
6. SplittingSizes
public class RegexSplit {
Answers
(a) 1j2
(b) 1j0
(c) 0j2
(d) Throws an exception
(e) None of the above
public static void main(String[] args) {
String[] nothing = "".split(":");
String[] bunchOfNothing = ":".split(":");
System.out.printf("%d|%d%n", nothing.length,
bunchOfNothing.length);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
7. SplittingSizes
public class RegexSplit {
Answers
(a) 1j2
(b) 1j0 - Explanation follows. . .
(c) 0j2
(d) Throws an exception
(e) None of the above
public static void main(String[] args) {
String[] nothing = "".split(":");
String[] bunchOfNothing = ":".split(":");
System.out.printf("%d|%d%n", nothing.length,
bunchOfNothing.length);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
8. If you navigate through the source for String.split, you’ll discover
that str.split(":") is effectively the same as
Pattern.compile(":").split(str, 0).
so. . . lets look there:
Pattern.split(Charsequence, int):
If this pattern does not match any subsequence of the input
then the resulting array has just one element, namely the
input sequence in string form.
If n is zero then the pattern will be applied as many times as
possible, the array can have any length, and trailing empty
strings will be discarded. [ emphasis added. ]
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
9. Joy of sets
import java.net.*;
public class UrlSet {
private static final String[] URL_NAMES = {
"http://javapuzzlers.com",
"http://www.summerartcircle.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
"http://www.cs.umd.edu"
};
public static void main(String[] args) throws Exception {
Set<URL> favourites = new HashSet<URL>();
for (String urlName : URL_NAMES){
favourites.add(new URL(urlName));
}
System.out.println(favourites.size());
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
10. Joy of sets
import java.net.*;
public class UrlSet {
Answers
(a) 4
(b) 5
(c) Throws an exception
(d) None of the above
private static final String[] URL_NAMES = {
"http://javapuzzlers.com",
"http://www.summerartcircle.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
"http://www.cs.umd.edu"
};
public static void main(String[] args) throws Exception {
Set<URL> favourites = new HashSet<URL>();
for (String urlName : URL_NAMES){
favourites.add(new URL(urlName));
}
System.out.println(favourites.size());
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
11. Joy of sets
import java.net.*;
public class UrlSet {
Answers
(a) 4 (assuming you are connected
private static final String[] URL_NAMES = {
to the net)
"http://javapuzzlers.com",
"http://www.summerartcircle.com",
"http://www.google.com",
"http://javapuzzlers.com",
"http://findbugs.sourceforge.net",
"http://www.cs.umd.edu"
(b) 5
(c) Throws an exception
(d) None of the above - it varies
from run to run
};
public static void main(String[] args) throws Exception {
Set<URL> favourites = new HashSet<URL>();
for (String urlName : URL_NAMES){
favourites.add(new URL(urlName));
}
System.out.println(favourites.size());
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
12. URL equals and hashCode are broken!
Two URL objects are equal if they have the same protocol, reference
equivalent hosts, have the same port number on the host, and the
same file and fragment of the file.
Two hosts are considered equivalent if both host names can be
resolved into the same IP addresses; else if either host name can’t be
resolved, the host names must be equal without regard to case; or
both host names equal to null.
Since hosts comparison requires name resolution, this operation is a
blocking operation.
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
13. Another look
public class Histogram {
private static final String[] words = { "I", "recommend",
"polygene", "lubricants" };
public static void main(String[] args) {
int[] histogram = new int[5];
for (String word1 : words) {
for (String word2 : words) {
String pair = word1 + word2;
int bucket = Math.abs(pair.hashCode())
% histogram.length;
histogram[bucket]++;
}
}
int pairCount = 0;
for (int freq : histogram) {
pairCount += freq;
}
System.out.println(’C’ + pairCount);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
14. Another look
public class Histogram {
Answers
(a) 83
(b) C16
(c) S
(d) None of the above
private static final String[] words = { "I", "recommend",
"polygene", "lubricants" };
public static void main(String[] args) {
int[] histogram = new int[5];
for (String word1 : words) {
for (String word2 : words) {
String pair = word1 + word2;
int bucket = Math.abs(pair.hashCode())
% histogram.length;
histogram[bucket]++;
}
}
int pairCount = 0;
for (int freq : histogram) {
pairCount += freq;
}
System.out.println(’C’ + pairCount);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
15. Another look
public class Histogram {
Answers
(a) 83
(b) C16
(c) S
(d) None of the above - throws
private static final String[] words = { "I", "recommend",
"polygene", "lubricants" };
public static void main(String[] args) {
int[] histogram = new int[5];
for (String word1 : words) {
for (String word2 : words) {
ArrayOutOfBoundsException
String pair = word1 + word2;
int bucket = Math.abs(pair.hashCode())
% histogram.length;
histogram[bucket]++;
}
}
int pairCount = 0;
for (int freq : histogram) {
pairCount += freq;
}
System.out.println(’C’ + pairCount);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
16. Math.abs(int) can return a negative number, and so can the %
operator
The hashcode of “polygenelubricants” is actually
Integer.MIN_VALUE i.e.
"polygenelubricants".hashCode() == Integer.MIN_VALUE
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
17. Long division
public class LongDivision {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
18. Long division
public class LongDivision {
public static void main(String[] args) {
final long MICROS_PER_DAY = 24 * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24 * 60 * 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}
Answers
(a) 0
(b) 5
(c) 1000
(d) Throws an exception
(e) None of the above
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
19. Long division answer
public class LongDivision {
public static void main(String[] args) {
//Multiplication is not with long numbers!
final long MICROS_PER_DAY = 24L * 60 * 60 * 1000 * 1000;
final long MILLIS_PER_DAY = 24L * 60 * 60 * 1000;
System.out.println(MICROS_PER_DAY / MILLIS_PER_DAY);
}
}
Answers
(a) 0
(b) 5 - not actually long division
(c) 1000
(d) Throws an exception
(e) None of the above
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
20. The Dating Game
import java.util.*;
public class DatingGame {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(1999, 12, 31); // Year, Month, Day
System.out.print(cal.get(Calendar.YEAR) + " ");
Date d = cal.getTime();
System.out.print(d.getDay() + " ");
System.out.println(cal.get(Calendar.DAY_OF_MONTH));
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
21. The Dating Game
import java.util.*;
public class DatingGame {
Answers
(a) 1999 31 31
(b) 1999 31 1
(c) 2000 1 31
(d) 2000 31 31
(e) None of the above
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(1999, 12, 31); // Year, Month, Day
System.out.print(cal.get(Calendar.YEAR) + " ");
Date d = cal.getTime();
System.out.print(d.getDay() + " ");
System.out.println(cal.get(Calendar.DAY_OF_MONTH));
}
}
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
22. The Dating Game
import java.util.*;
public class DatingGame {
Answers
(a) 1999 31 31
(b) 1999 31 1
(c) 2000 1 31 - maybe the Y2K
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(1999, 12, 31); // Year, Month, Day
System.out.print(cal.get(Calendar.YEAR) + " ");
Date d = cal.getTime();
System.out.print(d.getDay() + " ");
System.out.println(cal.get(Calendar.DAY_OF_MONTH));
}
}
problem?
(d) 2000 31 31
(e) None of the above
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
23. The Dating Game - answer
When the Java platform was first released, its only support for
calendar calculations was the Date class. This class was limited in
power, especially when it came to support for internationalization, and
it had a basic design flaw: Date instances were mutable. In release
1.1, the Calendar class was added to the platform to rectify the
shortcomings of Date; most Date methods were deprecated.
Unfortunately, this only made a bad situation worse.
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
24. The Dating Game - answer
When the Java platform was first released, its only support for
calendar calculations was the Date class. This class was limited in
power, especially when it came to support for internationalization, and
it had a basic design flaw: Date instances were mutable. In release
1.1, the Calendar class was added to the platform to rectify the
shortcomings of Date; most Date methods were deprecated.
Unfortunately, this only made a bad situation worse.
The program just illustrates some of the shortcomings in the current
API. The Calendar doesn’t warn us when it overflows and the months
start the count from 0
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
25. The Dating Game - answer
When the Java platform was first released, its only support for
calendar calculations was the Date class. This class was limited in
power, especially when it came to support for internationalization, and
it had a basic design flaw: Date instances were mutable. In release
1.1, the Calendar class was added to the platform to rectify the
shortcomings of Date; most Date methods were deprecated.
Unfortunately, this only made a bad situation worse.
The program just illustrates some of the shortcomings in the current
API. The Calendar doesn’t warn us when it overflows and the months
start the count from 0
Use Joda Time which will be included in java8. . .
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
26. Some comments and references
Use Sonar which will catch some of the problems from this
presentation with the findbugs plugin
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls
27. Some comments and references
Use Sonar which will catch some of the problems from this
presentation with the findbugs plugin
Clickable links:
Advanced Topics in Programming Languages: Java Puzzlers
Java-Puzzlers InfoQ
Nikola Petrov<nikola.petrov@ontotext.com> Java puzzlers - Traps, Pitfalls