guava学习:RangeSet

淡淡的烟草味﹌ 2021-06-24 14:37 578阅读 0赞

RangeSet类是用来存储一些不为空的也不相交的范围的数据结构。假如需要向RangeSet的对象中加入一个新的范围,那么任何相交的部分都会被合并起来,所有的空范围都会被忽略。

  讲了这么多,我们该怎么样利用RangeSet?RangeSet类是一个接口,需要用它的子类来声明一个RangeSet型的对象,实现了RangeSet接口的类有ImmutableRangeSet和TreeRangeSet,ImmutableRangeSet是一个不可修改的RangeSet,而TreeRangeSet是利用树的形式来实现。下面主要谈TreeRangeSet的用法:

  1. import com.google.common.collect.*;
  2. /**
  3. * User: 过往记忆
  4. * Email:wyphao.2007@163.com
  5. * Blog: https://www.iteblog.com
  6. * Date: 13-7-17
  7. * Time: 下午4:10
  8. */
  9. public void testRangeSet(){
  10. RangeSet rangeSet = TreeRangeSet.create();
  11. rangeSet.add(Range.closed(1, 10));
  12. System.out.println(rangeSet);
  13. rangeSet.add(Range.closedOpen(11, 15));
  14. System.out.println(rangeSet);
  15. rangeSet.add(Range.open(15, 20));
  16. System.out.println(rangeSet);
  17. rangeSet.add(Range.openClosed(0, 0));
  18. System.out.println(rangeSet);
  19. rangeSet.remove(Range.open(5, 10));
  20. System.out.println(rangeSet);
  21. }

输出:

  1. {[110]}
  2. {[110][1115)}
  3. {[110][1115)(1520)}
  4. {[110][1115)(1520)}
  5. {[15][1010][1115)(1520)}

注意:RangeSet需要充分利用JDK 1.6中NavigableMap特性,所以JDK1.6以下版本无法使用

1、那如果我们需要遍历rangeSet中的所有元素可以用下面方法实现

  1. public void iteratorRangeSet(RangeSet integerRangeSet) {
  2. if(integerRangeSet == null){
  3. return;
  4. }
  5. Set<Range> ranges = integerRangeSet.asRanges();
  6. Iterator<Range> iterator = ranges.iterator();
  7. while(iterator.hasNext()){
  8. Range next = iterator.next();
  9. System.out.println(next);
  10. }
  11. }

结果:

  1. [15]
  2. [1010]
  3. [1115)
  4. (1520)

2、如果我们需要得到rangeSet互补的范围,我们可以用RangeSet提供的complement()方法,rangeSet.complement()同样是一个RangeSet,其中的元素也是互不相交、且不为空的RangeSet,那么rangeSet的互补集可以像下面这样来写:

  1. RangeSet complement = rangeSet.complement();
  2. System.out.println(complement);

得到的结果是:

  1. {(-∞‥1)(510)(1011)[1515][20‥+∞)}

正好是rangeSet的互补。

3、如果需要在rangeSet中查询某个元素是否在rangeSet中,可以用contains(C)来实现,其中C extends java.lang.Comparable。比如我想得到上述rangeSet是否包含15,可以这样写:

  1. boolean isIn = rangeSet.contains(15);
  2. System.out.println(isIn);//false,因为上述范围不包含元素15.

4、如果想知道某个元素是在rangeSet中哪个范围里面,可以这样写:

  1. Range integerRange = rangeSet.rangeContaining(17);
  2. System.out.println(integerRange);
  3. //输出(15‥20),因为17被包含在(15‥20)中,所以输出这个范围。

5、如果想知道某个范围是否包含在rangeSet的范围中,可以这样写:

  1. boolean encloses = rangeSet.encloses(Range.closedOpen(18, 20));
  2. System.out.println(encloses);//true.因为范围(18,20)包含在范围(15,20)中
  3. encloses = rangeSet.encloses(Range.closedOpen(5, 20));
  4. System.out.println(encloses);//false.因为范围(5,20)不被rangeSet中任何范围包含.

发表评论

表情:
评论列表 (有 0 条评论,578人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Guava学习笔记:EventBus

    EventBus是Guava的事件处理机制,是设计模式中的观察者模式(生产/消费者编程模型)的优雅实现。对于事件监听和发布订阅模式,EventBus是一个非常优雅和简单解决方案

    相关 Guava学习笔记:Range

    在Guava中新增了一个新的类型Range,从名字就可以了解到,这个是和区间有关的数据结构。从Google官方文档可以得到定义:Range定义了连续跨度的范围边界,这个连续跨度

    相关 guava学习RangeSet

    RangeSet类是用来存储一些不为空的也不相交的范围的数据结构。假如需要向RangeSet的对象中加入一个新的范围,那么任何相交的部分都会被合并起来,所有的空范围都会被忽略。