... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2012-05-03

Java TreeMap Limitation (Bug?)

Consider a Java (1.6.0_21 or 1.7.0_03) TreeMap:

TreeMap<String, Double> map = new TreeMap<String, Double>();
map.put("m", 1.0);

We can extract the set of keys using navigableKeySet():

map.navigableKeySet()
// --> [m]

We can also ask for all of the keys on or after "a"::

map.navigableKeySet().tailSet("a")
// --> [m]

Or we can ask for all of the keys between "e" and "q" (exclusive):

NavigableSet subset = map.navigableKeySet().subSet("e", false, "q", false);
subset
// --> [m]

A limitation arises if we attempt to process this last subset further. Let's say that another component, unaware of how this subset was generated, attempts to find all keys after "d":

subset.tailSet("d")
// java.lang.IllegalArgumentException: fromKey out of range

This last expression throws an exception. The documentation for NavigableSet#subset() states that:

The returned set will throw an IllegalArgumentException on an attempt to insert an element outside its range.

Apparently, it also throws that exception even if you simply attempt to reference a key outside of its range. I suppose that it is (barely) defensible behaviour on the grounds that client code that is aware of the lineage of the subset may then later attempt to insert elements into the resulting tail-set that were outside of the original subsetted range. However, I would argue that the exception should be thrown if such an attempt were actually made, rather than just because it potentially could be made. I claim that this is a bug.

Blog Archive