This is a small code snippet and what I call an “IntervalMap”.
Basicly what it does is mapping an interval onto a value. For example
[0,5) → object1
[5,10) → object2
The idea is that if you give a key that is in one of the intervals that you get the object associated with that interval
For example:
‘3’ will be mapped on object1
public class IntervalMap<K extends Comparable<K>, V> extends
TreeMap<K, V> {
V defaultValue = null;
public IntervalMap(V defaultValue) {
super();
this.defaultValue = defaultValue;
}
/**
*
* Get the value corresponding to the given key
*
* @param key
* @return The value corresponding to the largest key 'k' so that
* " k is the largest value while being smaller than 'key' "
*/
public V getValue(K key) {
// if it is equal to a key in the map, we can already return the
// result
if (containsKey(key))
return super.get(key);
// Find largest key 'k' so that
// " k is the largest value while being smaller than 'key' "
// highest key
K k = lastKey();
while (k.compareTo(key) != -1) {
k = lowerKey(k);
if (k == null)
return defaultValue;
}
return super.get(k);
}
@Override
public V get(Object key) {
return getValue((K) key);
}
}
In code:
IntervalMap<Integer, String> map = new InterValMap<Integer,String>(null); map.put(0,”interval 1”) map.put(5,”interval 2”); System.out.println(map.get(3)); //output: “interval 1” System.out.println(map.get(5)); //output: “interval 2”
If you want to put a maximum limit on it you should add a value (like null) that you can detect as invalid. The default value you have to set in the constructor is only returned if a key is given that is under the minimum key value in the intervalmap. In this case everything smaller than zero
.
//upper limit [10,+oo) map.put(10,null);
If you have ideas on improving this code snippet. Or if you like it ![]()
Please let me know in the comments below!
Computer Based Math
class MapObject:
def __init__(self,default = None):
self.default = default
self.mapping = {}
def add(self,value,obj):
self.mapping[value]=obj
def get(self,value):
if value value ] + [self.default])[0]
Minimal python solution. Not the must efficient although
class MapObject: def __init__(self,default = None): self.default = default self.mapping = {} def add(self,value,obj): self.mapping[value]=obj def get(self,value): if value < 0: return self.default return ([ self.mapping[i] for i in sorted(self.mapping.keys()) if i> value ] + [self.default])[0]This is a bad idea:
while (k.compareTo(key) != -1) { … }
The documentation for Comparable.compareTo specifies that this method “returns a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.” Although some implementations only ever return 1, 0 and -1, this is certainly *not* guaranteed and *not* necessary. In fact, many implementations use something like “return this.a – other.a” to compare on the “a” field. This is conform with the specification, but will not work in your application.
A proper use of compareTo could look like:
while (k.compareTo(key) >= 0) { … }
Besides, why do you need the loop? Why do you need to start at the last key? Why can’t you simply use floorKey(K)?
Also, the “default value” mechanism could be implemented as a separate wrapper class, which *only* overrides get(K). Your IntervalMap could simply return null if there’s no closest value, and your wrapper could map that to a default value. Separation of concerns, remember?
You are right! I don’t need the loop, floorkey is awesome. Should have read the api more thoroughly
The solution you propose for the default value might be a cleaner way.
About the compareto, thanks! I wasn’t aware of that