Java puzzles

27
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<[email protected]> Java puzzlers - Traps, Pitfalls

Transcript of Java puzzles

Page 1: Java puzzles

Introduction - what this is about

Puzzles in java are those situations where the code is broken andyou are tricked by some API or the language itself.

Those were started mostly by Joch Bloch and there even abook(some of the examples are taken from there)Want it to be interactive

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 2: Java puzzles

Introduction - what this is about

Puzzles in java are those situations where the code is broken andyou are tricked by some API or the language itself.Those were started mostly by Joch Bloch and there even abook(some of the examples are taken from there)

Want it to be interactive

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 3: Java puzzles

Introduction - what this is about

Puzzles in java are those situations where the code is broken andyou are tricked by some API or the language itself.Those were started mostly by Joch Bloch and there even abook(some of the examples are taken from there)Want it to be interactive

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 4: Java puzzles

Awards as I think you will be lazy

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 5: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 6: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers

(a) 1|2(b) 1|0(c) 0|2(d) Throws an exception

(e) None of the above

Page 7: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers

(a) 1|2(b) 1|0 - Explanation follows. . .

(c) 0|2(d) Throws an exception

(e) None of the above

Page 8: Java puzzles

If you navigate through the source for String.split, you’ll discoverthat 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 inputthen the resulting array has just one element, namely theinput sequence in string form.

If n is zero then the pattern will be applied as many times aspossible, the array can have any length, and trailing emptystrings will be discarded. [ emphasis added. ]

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 9: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 10: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers(a) 4

(b) 5

(c) Throws an exception

(d) None of the above

Page 11: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers(a) 4 (assuming you are connected

to the net)

(b) 5

(c) Throws an exception

(d) None of the above - it variesfrom run to run

Page 12: Java puzzles

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 thesame file and fragment of the file.

Two hosts are considered equivalent if both host names can beresolved into the same IP addresses; else if either host name can’t be

resolved, the host names must be equal without regard to case; orboth host names equal to null.

Since hosts comparison requires name resolution, this operation is ablocking operation.

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 13: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 14: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers(a) 83

(b) C16

(c) S

(d) None of the above

Page 15: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers(a) 83

(b) C16

(c) S

(d) None of the above - throwsArrayOutOfBoundsException

Page 16: Java puzzles

Math.abs(int) can return a negative number, and so can the %operator

The hashcode of “polygenelubricants” is actuallyInteger.MIN_VALUE i.e.

"polygenelubricants".hashCode() == Integer.MIN_VALUE

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 17: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 18: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 19: Java puzzles

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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 20: Java puzzles

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, DaySystem.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<[email protected]> Java puzzlers - Traps, Pitfalls

Page 21: Java puzzles

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, DaySystem.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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers(a) 1999 31 31

(b) 1999 31 1

(c) 2000 1 31

(d) 2000 31 31

(e) None of the above

Page 22: Java puzzles

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, DaySystem.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<[email protected]> Java puzzlers - Traps, Pitfalls

Answers(a) 1999 31 31

(b) 1999 31 1

(c) 2000 1 31 - maybe the Y2Kproblem?

(d) 2000 31 31

(e) None of the above

Page 23: Java puzzles

The Dating Game - answer

When the Java platform was first released, its only support forcalendar calculations was the Date class. This class was limited inpower, especially when it came to support for internationalization, andit had a basic design flaw: Date instances were mutable. In release1.1, the Calendar class was added to the platform to rectify theshortcomings 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 currentAPI. The Calendar doesn’t warn us when it overflows and the monthsstart the count from 0

Use Joda Time which will be included in java8. . .

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 24: Java puzzles

The Dating Game - answer

When the Java platform was first released, its only support forcalendar calculations was the Date class. This class was limited inpower, especially when it came to support for internationalization, andit had a basic design flaw: Date instances were mutable. In release1.1, the Calendar class was added to the platform to rectify theshortcomings 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 currentAPI. The Calendar doesn’t warn us when it overflows and the monthsstart the count from 0

Use Joda Time which will be included in java8. . .

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 25: Java puzzles

The Dating Game - answer

When the Java platform was first released, its only support forcalendar calculations was the Date class. This class was limited inpower, especially when it came to support for internationalization, andit had a basic design flaw: Date instances were mutable. In release1.1, the Calendar class was added to the platform to rectify theshortcomings 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 currentAPI. The Calendar doesn’t warn us when it overflows and the monthsstart the count from 0

Use Joda Time which will be included in java8. . .

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 26: Java puzzles

Some comments and references

Use Sonar which will catch some of the problems from thispresentation with the findbugs plugin

Clickable links:Advanced Topics in Programming Languages: Java Puzzlers

Java-Puzzlers InfoQ

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls

Page 27: Java puzzles

Some comments and references

Use Sonar which will catch some of the problems from thispresentation with the findbugs plugin

Clickable links:Advanced Topics in Programming Languages: Java Puzzlers

Java-Puzzlers InfoQ

Nikola Petrov<[email protected]> Java puzzlers - Traps, Pitfalls