You'd have to implement such a map yourself, I believe. You're right that it would have to be sorted; the implementation of get
would have to iterate through the keys until it finds the largest key that is less than or equal to the argument.
If you subclass TreeMap
it would initially appear that you can get this working via simply overriding the get()
method. However, to maintain as much of the Map contract as possible you'll have to override other methods for consistency.
And what about e.g. containsKey()
? Does your main contain a mapping for 40
? If you return false
, then a client can decide not to call get()
based on this information; for these reason (and the formal definition) you have to return true
. But then it makes it hard to determine whether the map "really contains" a given mapping; if you're looking to do something such as update without overwriting anything that already exists.
The remove()
method might be tricky too. From my reading of the interface,
// Calling map.remove "Removes the mapping for a key from this map if it is present."
map.remove(x);
// Now that the mapping is removed, I believe the following must hold
assert map.get(x) == null;
assert map.containsKey(x);
Acting consistently here would be very tricky. If you have a mapping from 35-40 for example, and you call remove(38)
, then as I understand it you'd have to return null
for any subsequent gets for the key 38, but return the aforementioned mapping for keys 35-37 or 39-40.
So while you can make a start on this by overriding TreeMap, perhaps the whole concept of Map
is not quite what you want here. Unless you need this behaviour to slot into existing methods that take Map
, it might be easier to create it yourself as a distinct class since it's not quite a Map, the way you're defining it.