January 2004 Archives

0*Infinity==NaN; 1/-Infinity==-0

The Java floating-point types have special values for negative zero, positive and negative infinity, and not-a-number, or NaN. I hacked up a short program (below) to print out a multiplication table for these special values, and also tables for the +, -, /, and % operators as well. For the most part, these special values behave as you'd expect when you do arithmetic with them. But some of the values produce results that may seem suprising. 1/0 produces infinity, of course, but 0/0 produces NaN which may not be obvious at first. (If you divide by zero using an integer type instead of a floating point type, you get an ArithmeticException. Floating-point arithmetic never throws exceptions in Java.)

The code is below. Cut, paste, compile and run..

MyDoom mailbox cleanup as a learning experience

When I chose my PopClean.java mailbox cleaner utility as the subject of the first entry of my new blog, I didn't think I'd be using it again just a few days later....

A good spam filter will delete these messages for you, but if you do your filtering on the client side, then you still have to download all the spam. My utility is based on the fact that virus-spawned spam has predictable subject lines and sizes. It deletes the messages directly from the POP mailbox without ever downloading them.

If you're going to have to delete a bunch of virus-generated messages from your inbox, you might as well make a learning experience out of it. Here's what I did to clean my mailbox...

Failure to override

| 8 Comments

22 months ago, I wrote this article for ONJava.com (part of the O'Reilly Network.

I'd pretty much forgotten about the article, until I got an e-mail today from a New Zealand reader known simply as "Hemi". He was the first of (presumably) several thousand readers to point out an error in this code from the article:

public class LRUCache extends java.util.LinkedHashMap {
    public LRUCache(int maxsize) {
	super(maxsize*4/3 + 1, 0.75f, true);
	this.maxsize = maxsize;
    }
    protected int maxsize;
    protected boolean removeEldestEntry() { 
       return size() > maxsize; 
    }
}

This code is supposed to implement a least-recently-used (LRU) cache on top of the java.util.LinkedHashMap class. Can you spot the error? Hint: the class functions as a cache, but fails the LRU part.

Read on to see what I did wrong and learn how you can avoid this category of errors yourself.

Fun with Java Sound

One of the new chapters I added to the 3rd edition of Java Examples in a Nutshell covers the Java Sound API. That chapter was a lot of fun to research and write.

To the right is an applet I played around with before writing the example that actually made it into the chapter: its a MIDI drum machine. Click your mouse in the applet to give it keyboard focus and then strike keys at random to generate percussion effects. Move the mouse to the bottom of the applet for louder sounds and to the top of the applet for softer sounds. Play around with the keys: only keys whose keycode maps to a MIDI key number between 35 and 81 produce any sound.

You'll need the Java 1.4 plugin installed in your browser for this to work, of course. Don't forget to click on the applet. If you don't it may never get the keyboard events it needs.

Please excuse the lame visuals, and take a look at the surprisingly simple source code.

Big Changes in Java 1.5 Alpha

Java 1.5 introduces major new changes to the language.
And there is now an alpha release so you can try them out.

The alpha release doesn't include documentation, but the JSRs that define the language features are in public review at the JCP, which means that you can learn about (and coment on, if you choose) these new features.

First up is JSR 14 which adds parameterized types to the language. This is huge. You can use types like:

Map<String,Integer> map = new HashMap<String,Integer>

The public review draft for this is really old, and slighly out of sync with reality. There ought to be a new version soon.

Next is JSR 201, a catch-all for five smaller, but no less exciting, language changes. They are:

0xCoffeeCabal

The other day I tried to come up with a Java hexadecimal literal that was cooler (and less tainted by sexism) than the ubiquitous 0xCAFEBABE. 0xCAFED00D is misspelled, and 0xDEADBEEF is not suitable for vegetarians.

So like any good Unix user, I came up with this:

grep -i '^[abcdef][abcdefo]*l\?$' /usr/share/dict/words

(The trailing letter l in the regular expression is legal: it is used in Java literals to signify a long instead of an int.)

My favorites?

PopClean.java

PopClean is a simple Java utility program I put together to deal with the flood of viral SoBig.F-generated email messages clogging my POP3 inbox. I have included it as an example in the (newly released) third edition of Java Examples in a Nutshell.

PopClean scans a POP3 inbox and can list or delete messages that are above a size you specify. You can also constrain the list or deletion to messages whose Subject: lines match a given regular expression. It does this without having to download the entire message. Since SoBig messages are ~100Kb each, this is a big win in terms of bandwidth.

I've placed this program in the public domain. It comes with NO WARRANTY, and you have to use it at your own risk. I've used it on two different POP3 servers, but have not tried to test it rigorously. It requires Java 1.4 (for regular expression matching).

I'm sure there are other utilities like this one out there. I wrote this while I was in the middle of updating Java Examples in a Nutshell, however, and rolling my own version just seemed like the right thing to do. In addition to its utility, this program also serves as an example of how easy it is to write networked programs in Java.

The code follows...

Books

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

The classic Java quick-reference