有没有办法让像ArrayListMultimap这样的地图,但有RangeSet和"合并"代替?

时间:2016-09-04 18:36:37

标签: java guava multimap

我想要一个地图,它将RangeSets分配给整数,而不是:

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);
}

我会写:

sensorIDsWithTimeRange.put(sensorId, Range.closedOpen(startTime, endTime));

如果密钥尚未存在,它将创建一个新密钥,或者将新范围插入已存在的RangeSet,并在密钥存在时合并它。

1 个答案:

答案 0 :(得分:2)

您可以使用java.util.AbstractMap快速创建自己的自定义Map类型:

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();
    }
}

使用示例:

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);

示例输出:

{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)]}