I want a map which assignes RangeSets to Integers in a way that instead of:
Map<Integer, RangeSet> sensorIDsWithTimeRange = new HashMap<>();
if (sensorIDsWithTimeRange.containsKey(sensorId)) {
sensorIDsWithTimeRange.get(sensorId).add(Range.closedOpen(startTime, endTime));
} else {
RangeSet<Integer> rangeSet = TreeRangeSet.create();
rangeSet.add(Range.closedOpen(startTime, endTime));
sensorIDsWithTimeRange.put(sensorId, rangeSet);
}
I would write just:
sensorIDsWithTimeRange.put(sensorId, Range.closedOpen(startTime, endTime));
And it would create a new key if the key not already exists or insert new range to already existing RangeSet and coalescent it if the key exists.
You can use java.util.AbstractMap
to quickly create your own custom Map
type:
public class RangeSetHashMap<K, V extends Comparable> extends AbstractMap<K, RangeSet<V>> {
private final Map<K, RangeSet<V>> map = new HashMap<>();
public RangeSet<V> put(K key, Range<V> value) {
RangeSet<V> rangeSet = computeIfAbsent(key, k -> TreeRangeSet.create());
rangeSet.add(value);
return rangeSet;
}
@Override
public RangeSet<V> put(K key, RangeSet<V> value) {
return map.put(key, value);
}
@Override
public Set<Entry<K, RangeSet<V>>> entrySet() {
return map.entrySet();
}
}
Example usage:
RangeSetHashMap<Integer, Time> sensorIDsWithTimeRange = new RangeSetHashMap<>();
sensorIDsWithTimeRange.put(0, Range.closedOpen(valueOf("12:30:00"), valueOf("12:40:00")));
sensorIDsWithTimeRange.put(0, Range.closedOpen(valueOf("17:09:42"), valueOf("23:06:33")));
sensorIDsWithTimeRange.put(1, Range.closedOpen(valueOf("04:13:56"), valueOf("04:14:02")));
System.out.println(sensorIDsWithTimeRange);
sensorIDsWithTimeRange.put(0, Range.closedOpen(valueOf("02:11:12"), valueOf("12:45:19")));
System.out.println(sensorIDsWithTimeRange);
Example output:
{0=[[12:30:00‥12:40:00), [17:09:42‥23:06:33)], 1=[[04:13:56‥04:14:02)]}
{0=[[02:11:12‥12:45:19), [17:09:42‥23:06:33)], 1=[[04:13:56‥04:14:02)]}