区间映射 -- RangeMap

2018-02-07 17:34:39   最后更新: 2018-02-07 17:34:39   访问数量:266




上一篇日志中,我们介绍了 guava 的 RangeSet 容器:

区间集合 -- RangeSet

本篇日志我们来介绍区间容器家族的另一个成员 -- RangeMap

RangeSet 是一组区间的集合,然而有时,我们需要通过区间映射到一个值,也就是需要一个 map,他的 key 是 Range,value 是我们需要的值,这就是 RangeMap 的强大功能

对于不同的时间段内,展示不同的文案等类似的功能,使用 RangeMap 将十分便捷

 

RangeMap 的实现

RangeMap 和 RangeSet 类似,拥有两个实现:

  • TreeRangeMap -- 基于红黑树实现的拥有排序的 RangeMap
  • ImmutableRangeMap -- 不可变的 RangeMap

 

下面我们以 TreeRangeMap 为例来进行介绍

 

RangeMap 的创建方法

TreeRangeMap 提供了 create 方法:

public static <K extends Comparable, V> TreeRangeMap<K, V> create()

 

 

只需要执行:

RangeMap<Long, Integer> rangeMap = TreeRangeMap.create();

 

即可创建一个 RangeMap

 

添加区间 -- put

RangeMap 可以通过 put 操作添加元素

public void put(Range<K> range, V value)

 

 

  • 示例
RangeMap<Integer, String> rangeMap = TreeRangeMap.create(); rangeMap.put(Range.closed(1, 13), "hello"); rangeMap.put(Range.closed(10, 15), "world"); System.out.println(rangeMap); System.out.println(rangeMap.get(10));

 

 

打印出了:

[[1..10)=hello, [10..15]=world] world

 

可以看到,如果区间有重合,put 操作会覆盖掉原有的重叠区间,保证了 RangeMap 中作为 key 的区间无重叠

 

putCoalescing

putCoalescing 操作是另一个元素添加操作,他与 put 最大的区别是是否连接两个 Range

public void putCoalescing(Range<K> range, V value)

 

 

  • 示例
RangeMap<Integer, String> rangeMap = TreeRangeMap.create(); rangeMap.put(Range.closedOpen(1, 10), "hello"); rangeMap.put(Range.closed(10, 15), "hello"); System.out.println(rangeMap); System.out.println(rangeMap.get(10));

 

 

上面的例子输出了:

[[1..10)=hello, [10..15]=hello] hello

 

可以看到,虽然先后两次 put 的区间范围是连接的,而实际的存储和查询仍然是按照每次插入的覆盖原则分开的,而实际上,我们很多情况下是希望他们能够连接成为一个区间的,这就是 putCoalescing 方法的作用了

 

RangeMap<Integer, String> rangeMap = TreeRangeMap.create(); rangeMap.put(Range.closedOpen(1, 10), "hello"); rangeMap.putCoalescing(Range.closed(10, 15), "hello"); System.out.println(rangeMap); System.out.println(rangeMap.get(10));

 

 

上面的例子输出了:

[[1..15]=hello] hello

 

 

putAll

另一个插入操作是 putAll 操作

public void putAll(RangeMap<K, V> rangeMap)

 

他将另一个 RangeMap 中的全部元素添加到当前 RangeMap 中,他是通过 put 方法实现的

 

元素删除操作

public void remove(Range<K> rangeToRemove)

 

 

删除一个区间

 

获取 Range 的 Map -- asMapOfRanges

RangeMap 可以看做是 key 是 Range 对象的 Map 集合,因此有时直接使用 Map<Range<K>, V> 的集合也是很有用的:

public Map<Range<K>, V> asMapOfRanges()

 

 

获取 Range 的逆序 Map -- asDescendingMapOfRanges

Map<Range<K>, V> asDescendingMapOfRanges()

 

 

获取值所在的区间和 value 组成的 Entry -- getEntry

既然是一个 Map 结构,要获取 Map 中的一个元素,那就需要 Entry<Range<K, V>, V> 结构

getEntry 方法返回了参数所在区间为 key 的 Entry 对象

public Entry<Range<K>, V> getEntry(K key)

 

 

获取参数对应的值 -- get

get 方法获取了参数所在区间对应的值:

public V get(K key)

 

 

扩充集合 -- span

与 RangeSet 一样,RangeMap 也拥有 span 方法,他范围所有作为 key 的区间的跨越范围

public Range<K> span()

 

 






技术帖      apache      龙潭书斋      java      range      map      guava      区间      映射     


京ICP备15018585号