Java Code Talk, Part 3
Neal: Hello and welcome to Code Talk with your hosts, Click and Hack, the type-it brothers!
Josh: Hi. Let's give the answers to last week's puzzlers. In the first one you were asked to write a method that takes a Vector of elements and returns a new Vector containing the same elements in the same order, with the second and subsequent occurrence of any duplicate elements removed.
Neal: It was a moderate pain: I iterated over the Vector putting the elements into a HashSet and...
Josh: Would you believe that you can do it in one line of code?
return new Vector(new LinkedHashSet(vec));
Neal: Hmm... I know that putting a bunch of elements into a set eliminates the duplicates, but how do you preserve the order? And what, pray tell, is a "LinkedHashSet"?
Josh: It's a new (v 1.4) Set implementation, a hash table with a linked list running through it. It runs almost as fast as a normal HashSet but it preserves insertion order. There's also a Map version (LinkedHashMap) that you can use to make a custom cache.
Neal: Sheesh. And to think that I wasted 15 minutes coding it up the hard way.
Josh: Well that's what you get for not keeping up with the latest enhancements to the libraries. The second puzzler was to write a method that takes a string containing tokens separated by commas and optional whitespace, and returns an array of strings representing the tokens.
Neal: It was a moderate pain: I tried using a StringTokenizer but the semantics weren't quite right and...
Josh: Would you believe that you can do it in one line of code?
return(s.split(",\\s*"));
Neal: Whoa... Does String really have a split method? An what's all that line noise in the argument.
Josh: String.split is a convenience method for the new (v 1.4) regular expression API (java.util.regex), and the "line noise" is a regular expression, wise guy. If you haven't used regular expressions before, they do look a bit cryptic, but they're amazingly powerful. This is one new API that's definitely worth learning. StringTokenizer is pretty much obsolete at this point.
Neal: I'll buy that for two bits. So what was the third puzzler?
Josh: You were asked to write a method that takes a sorted array of ints and a "target" int, returning true if the array contains the target, false if it doesn't.
Neal: And I suppose you're going to tell me there's a way to do it in one line?
Josh: Finally you're catching on. Just use the binarySearch method in java.util.Arrays:
return Arrays.binarySearch(sortedArray, target) >= 0;
Last week's final puzzler was to write a program that prints a message telling you how many times it's been run.
Neal: You're not going to tell me that it's a one-liner too?
Josh: Nope, it takes four lines (plus the usual boilerplate):
import java.util.prefs.Preferences; public class Counter { public static void main(String[] args) { Preferences p = Preferences.userNodeForPackage(Counter.class); int previousRuns = p.getInt("previousRuns", 0); System.out.println("This is run number " + previousRuns); p.putInt("previousRuns", previousRuns + 1); } }
Neal: Pretty slick. So what are Preferences?
Josh: A new (v 1.4) API for storing user preferences and configuration data. It can also be used to store small amounts of persistent data, as we just saw. It's a heck of a lot easier than rolling your own. That's the common theme connecting last week's puzzlers: know and use the libraries, and make it a point to keep up with the latest additions. It can save you oodles of time, which you can devote to higher purposes.
Neal: Now that's a lesson we can all live by. Anyway, on to this week's puzzlers. What does this program print, and why?
public class Truth { public static void main(String args[]) throws Throwable { new Foo(); } } class Foo { static Bar b = new Bar(); static boolean truth() { return true; } static final boolean TRUTH = truth(); Foo() { System.out.println("The truth is: " + TRUTH); } } class Bar extends Foo { }Josh: And here's another one to keep you thinking. What does this program print, and why?
public class Shifty { public static void main(String[] args) { int n = 0; while (-1 << n != 0) n++; System.out.println(n); } }
Neal: That's it for today. Don't forget, if you have a puzzler for us, write it on the back of a twenty dollar bill and send it to me.
Josh: Or email it to us at javapuzzlers@sun.com along with all of your credit card numbers.