Guava记录 - 新集合类型RangeMap
一、简介
Guava
- RangeMap
是Guava
中新出的集合类型。官网对其描述如下:
RangeMap is a collection type describing a mapping from disjoint, nonempty ranges to values. Unlike RangeSet, RangeMap never "coalesces" adjacent mappings, even if adjacent ranges are mapped to the same values.
大致意思为:
RangeMap
是一个新的集合类型.描述了不相交的、非空的范围到值得映射.RangeMap
从不“合并”相邻映射,即使将相邻的范围映射到相同的值.
可以理解为:
RangeMap
是基于RangeSet
的一个升级版类型,它可以将某段区间与某个值进行映射.不过和RangeSet
略有不同.之前提到了RangeSet
会将相邻的区间进行自动merge,并且仅仅只是维护了一个区间范围.而RangeMap
却是将区间范围和value
的关系映射了起来.因此在原有区间对应了值得情况下插入相交的区间,则会对相交部分的值做覆盖,原有区间做拆分.并且不提供补集的方法.
常用场景
重试机制
、阶梯式收费
等等......
二、常用方法
1、创建和填充
RangeMap
提供了和RangeSet
类似的创建方式,以及和map相似的数据填充方式.简单又便捷.
实验代码:
System.out.println("====================测试 new collection Types====================");
RangeMap<Integer, String> testRangeMap = TreeRangeMap.create();
//测试添加一个闭区间的map映射
testRangeMap.put(Range.closed(1, 10), "foo");
System.out.println("============测试添加一个闭区间的map映射结果============" + testRangeMap);
//测试添加一个开区间的map映射
testRangeMap.put(Range.open(3, 6), "bar");
System.out.println("============测试添加一个开区间的map映射结果============" + testRangeMap);
//测试添加一个相邻开区间的map映射
testRangeMap.put(Range.open(10, 20), "foo");
System.out.println("============测试添加一个相邻开区间的map映射结果============" + testRangeMap);
//测试移除一个闭区间的map映射
testRangeMap.remove(Range.closed(5, 11));
System.out.println("============测试移除一个闭区间的map映射============" + testRangeMap);
实验结果:
====================测试 new collection Types====================
============测试添加一个闭区间的map映射结果============[[1..10]=foo]
============测试添加一个开区间的map映射结果============[[1..3]=foo, (3..6)=bar, [6..10]=foo]
============测试添加一个相邻开区间的map映射结果============[[1..3]=foo, (3..6)=bar, [6..10]=foo, (10..20)=foo]
============测试移除一个闭区间的map映射============[[1..3]=foo, (3..5)=bar, (11..20)=foo]
可以看出当我们插入相交区间的时候RangeMap
会自动进行相交覆盖,不相交切割的处理.
当我们插入相邻区间映射的时候,会独立出来,并未进行merge.
当我们进行移除中间的区间时,也会进行切割操作,对原有范围内的区间进行处理,移除掉指定的部分,保留未移除的部分
2、迭代操作
RangeMap
本身是不支持迭代操作的,当我们想对RangeMap
的数据进行迭代操作的时候,RangeMap
提供了asMapOfRanges()
方法.它会把RangeMap
作为Map<Range<K>, V>.的形式返回.这样我们就可以进行迭代操作了.
实验代码:
//测试asMap
testRangeMap.asMapOfRanges().entrySet()
.stream()
.filter(Objects::nonNull)
.forEach(rangeStringEntry -> {
System.out.println("======current key======" + rangeStringEntry.getKey());
System.out.println("======current value======" + rangeStringEntry.getValue());
});
实验结果:
======current key======[1..3]
======current value======foo
======current key======(3..5)
======current value======bar
======current key======(11..20)
======current value======foo
3、取交集
除了上述的方法外,RangeMap
还提供了一个比较实用的方法.可以通过设定指定范围区间,获取当前RangeMap
的key值与指定区间相交的映射关系.
实验代码:
//测试交集map
System.out.println("============测试相交的区间范围映射=============" + testRangeMap.subRangeMap(Range.closed(1, 6)));
实验结果:
============测试相交的区间范围映射============={[1..3]=foo, (3..5)=bar}
......未完待续