Sunday, June 04, 2006

Stupid Tiger Tricks

[EDIT 22-09-2006: There is a bug on the mapWith code below. I explain what happened here.]

One of the things that bugs me about Java is that it lacks literal constructs for creating lists and maps*. This, coupled with the profusion of casts, can lead to APIs prefering arrays over collections, which are otherwise much easier to handle. Java 5 (Tiger) brought generics, helping to minimize all those annoying casts, but the verbosity for initializing collections is still an issue. Here is the result of a quick hack to try and improve things a bit:

public class Web2dot0 {
private List<String> buzzwords =
listWith("mashup", "AJAX", "bottom-up", "tagging");
private Map<Integer, String> strategy =
mapWith(pair(1, "Pretty AJAX UI"), pair(3, "profit!"));
...
}

This was implemented using an utility class with the following static members:

public class CollectionUtils {
public static <E> List<E> listWith(E... items) {
return Arrays.asList(items);
}
public static <K, V> Map<K, V> mapWith(Map.Entry<K, V>... entries) {
HashMap<K, V> map = new HashMap<K, V>();
for (Map.Entry<K, V> eachEntry : entries)
map.put(eachEntry.getKey(), eachEntry.getValue());
return map;
}
public static <K, V> Map.Entry<K, V> pair(K key, V val) {
return new ImmutablePair<K, V>(key, val);
}
public static final class ImmutablePair<K, V> implements Map.Entry<K,V> {...}
...
}

The listWith(), mapWith() and pair() methods were then static imported in the client class.

* And now the geniouses at the JCP want to create XML literals. That reminds me of a comment I read in Taenembaun's computer organization book, saying that if programmers could have their way in the chip design process, opperations like branchAndDoPayroll would be part of the ISA.