Thursday, November 27, 2008

Graphical cd

The following bash function allows you to change directory using a Directory chooser:
gcd() {
local CDTO=`zenity --title="cd" --file-selection --directory`
if [ -n "${CDTO}" ] ; then
cd "${CDTO}"
fi
}

Clips Eclipse Plug-in

Check out the new Clips Eclipse plug-in here.

Clips View


Clips Preferences

Thursday, November 13, 2008

Zero length Java array cache

Many times I find myself declaring private static final zero length array fields of some type or the other. Some times the zero length arrays for a same type are declared in more than one place. To avoid this, I came up with the simple zero length array cache backed by a WeakHashMap. The beauty of this is that it does not require a cast because it uses the generic method which uses the Class
as a type token.

import java.util.Map;
import java.util.WeakHashMap;

/**
* A simple cache using WeakHashMap of zero length arrays of a given class.
*
* @author schitale
*
*/
public class ZeroLength {
private static Map map = new WeakHashMap();

@SuppressWarnings("unchecked")
public static T[] array(Class c) {
T[] array = (T[]) map.get(c);
if (array == null) {
array = (T[]) java.lang.reflect.Array.newInstance(c, 0);
map.put(c, array);
}
return array;
}

public static void main(String[] args) {
System.out.println(array(String.class).getClass().getCanonicalName()
+ " of length " + array(String.class).length);
System.out.println(array(String[].class).getClass().getCanonicalName()
+ " of length " + array(String.class).length);
}
}
The output is:
java.lang.String[] of length 0
java.lang.String[][] of length 0

If you want to rely on the identity of the zero length array instance (e.g. == based comparison) then replace the WeakHashMap with HashMap. However, in that case you have to watch out for memory leaks through static fields of array component classes. You may want to add a method to remove the reference to the array from the HashMap.

Is there a better way to do this?

IMHO the java.lang.Class class should provide such factory method. This is along the lines of factory method:
public static final T  List T java.util.Collections.emptyList();


The implementation in java.lang.Class may look like:

private static T[] zeroLengthArray;

public static synchronized T[] emptyArray() {
if (zeroLengthArray == null) {
zeroLengthArray = (T[]) java.lang.reflect.Array.newInstance(this, 0);
}
return zeroLengthArray;
}