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.