Guava学习笔记:Range

2019-03-08 21:50|来源: 网络

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

  在数学里面的范围是有边界和无边界之分的;同样,在Guava中也有这个说法。如果这个范围是有边界的,那么这个范围又可以分为包括开集(不包括端点)和闭集(包括端点);如果是无解的可以用+∞表示。如果枚举的话,一共有九种范围表示:

Guava Range 概念,范围和方法
概念 表示范围 guava对应功能方法
(a..b) {x | a < x < b} open(C, C)
[a..b] {x | a <= x <= b}  closed(C, C)
[a..b) {x | a <= x < b} closedOpen(C, C)
(a..b] {x | a < x <= b} openClosed(C, C)
(a..+∞) {x | x > a} greaterThan(C)
[a..+∞) {x | x >= a} atLeast(C)
(-∞..b) {x | x < b} lessThan(C)
(-∞..b] {x | x <= b} atMost(C)
(-∞..+∞) all values all()

  上表中的guava对应功能方法那一栏表示Range类提供的方法,分别来表示九种可能出现的范围区间。如果区间两边都存在范围,在这种情况下,区间右边的数不可能比区间左边的数小。在极端情况下,区间两边的数是相等的,但前提条件是最少有一个边界是闭集的,否则是不成立的。比如:
  [a..a] : 里面只有一个数a;
  [a..a); (a..a] : 空的区间范围,但是是有效的;
  (a..a) : 这种情况是无效的,构造这样的Range将会抛出异常。
  在使用Range时需要注意:在构造区间时,尽量使用不可改变的类型。如果你需要使用可变的类型,在区间类型构造完成的情况下,请不要改变区间两边的数。

   实例:

public class TestBaseRange {
@Test
public void testRange(){ System.out.println("open:"+Range.open(1, 10)); System.out.println("closed:"+ Range.closed(1, 10)); System.out.println("closedOpen:"+ Range.closedOpen(1, 10)); System.out.println("openClosed:"+ Range.openClosed(1, 10)); System.out.println("greaterThan:"+ Range.greaterThan(10)); System.out.println("atLeast:"+ Range.atLeast(10)); System.out.println("lessThan:"+ Range.lessThan(10)); System.out.println("atMost:"+ Range.atMost(10)); System.out.println("all:"+ Range.all()); System.out.println("closed:"+Range.closed(10, 10)); System.out.println("closedOpen:"+Range.closedOpen(10, 10)); //会抛出异常 System.out.println("open:"+Range.open(10, 10)); } }

  此外,范围可以构造实例通过绑定类型显式,例如:

public class TestBaseRange {

    @Test
    public void testRange(){
        System.out.println("downTo:"+Range.downTo(4, BoundType.OPEN));
        System.out.println("upTo:"+Range.upTo(4, BoundType.CLOSED));
        System.out.println("range:"+Range.range(1, BoundType.CLOSED, 4, BoundType.OPEN)); 
    }
}

  输出:

downTo:(4‥+∞)
upTo:(-∞‥4]
range:[1‥4)

  操作方法

  1.contains:判断值是否在当前Range内

    @Test
    public void testContains(){
        System.out.println(Range.closed(1, 3).contains(2)); 
        System.out.println(Range.closed(1, 3).contains(4)); 
        System.out.println(Range.lessThan(5).contains(5)); 
        System.out.println(Range.closed(1, 4).containsAll(Ints.asList(1, 2, 3))); 
    }

  //=====输出=====
  true
  false
  false
  true

  2.Endpoint相关查询方法:

    @Test
    public void testQuery(){
        System.out.println("hasLowerBound:"+Range.closedOpen(4, 4).hasLowerBound()); 
        System.out.println("hasUpperBound:"+Range.closedOpen(4, 4).hasUpperBound()); 
        System.out.println(Range.closedOpen(4, 4).isEmpty()); 
        System.out.println(Range.openClosed(4, 4).isEmpty()); 
        System.out.println(Range.closed(4, 4).isEmpty()); 
        // Range.open throws IllegalArgumentException
        //System.out.println(Range.open(4, 4).isEmpty()); 

        System.out.println(Range.closed(3, 10).lowerEndpoint());
        System.out.println(Range.open(3, 10).lowerEndpoint()); 
        System.out.println(Range.closed(3, 10).upperEndpoint()); 
        System.out.println(Range.open(3, 10).upperEndpoint()); 
        System.out.println(Range.closed(3, 10).lowerBoundType()); 
        System.out.println(Range.open(3, 10).upperBoundType()); 
    }

  //======输出=======
  hasLowerBound:true
  hasUpperBound:true
  true
  true
  false
  3
  3
  10
  10
  CLOSED
  OPEN

   3.encloses方法:encloses(Range range)中的range是否包含在需要比较的range中

    @Test
    public void testEncloses(){
        Range<Integer> rangeBase=Range.open(1, 4);
        Range<Integer> rangeClose=Range.closed(2, 3);
        Range<Integer> rangeCloseOpen=Range.closedOpen(2, 4);
        Range<Integer> rangeCloseOther=Range.closedOpen(2, 5);
        System.out.println("rangeBase: "+rangeBase+" Enclose:"+rangeBase.encloses(rangeClose)+" rangeClose:"+rangeClose);
        System.out.println("rangeBase: "+rangeBase+" Enclose:"+rangeBase.encloses(rangeCloseOpen)+" rangeClose:"+rangeCloseOpen);
        System.out.println("rangeBase: "+rangeBase+" Enclose:"+rangeBase.encloses(rangeCloseOther)+" rangeClose:"+rangeCloseOther);
    }

  //=======输出========
  rangeBase: (1‥4) Enclose:true rangeClose:[2‥3]
  rangeBase: (1‥4) Enclose:true rangeClose:[2‥4)
  rangeBase: (1‥4) Enclose:false rangeClose:[2‥5)

  4.isConnected:range是否可连接上

    @Test
    public void testConnected(){
        System.out.println(Range.closed(3, 5).isConnected(Range.open(5, 10))); 
        System.out.println(Range.closed(0, 9).isConnected(Range.closed(3, 4)));
        System.out.println(Range.closed(0, 5).isConnected(Range.closed(3, 9))); 
        System.out.println(Range.open(3, 5).isConnected(Range.open(5, 10))); 
        System.out.println(Range.closed(1, 5).isConnected(Range.closed(6, 10)));
    }

  //======输出=========
  true
  true
  true
  false
  false

  4.intersection:如果两个range相连时,返回最大交集,如果不相连时,直接抛出异常

    @Test
    public void testIntersection(){
        System.out.println(Range.closed(3, 5).intersection(Range.open(5, 10))); 
        System.out.println(Range.closed(0, 9).intersection(Range.closed(3, 4))); 
        System.out.println(Range.closed(0, 5).intersection(Range.closed(3, 9))); 
        System.out.println(Range.open(3, 5).intersection(Range.open(5, 10)));
        System.out.println(Range.closed(1, 5).intersection(Range.closed(6, 10)));
    }

  //=======输出=========
  (5‥5]
  [3‥4]
  [3‥5]

  注意:第四和第五行代码,当集合不相连时,会直接报错

   5.span:获取两个range的并集,如果两个range是两连的,则是其最小range

 

    @Test
    public void testSpan(){
        System.out.println(Range.closed(3, 5).span(Range.open(5, 10))); 
        System.out.println(Range.closed(0, 9).span(Range.closed(3, 4))); 
        System.out.println(Range.closed(0, 5).span(Range.closed(3, 9))); 
        System.out.println(Range.open(3, 5).span(Range.open(5, 10))); 
        System.out.println(Range.closed(1, 5).span(Range.closed(6, 10)));
        System.out.println(Range.closed(1, 5).span(Range.closed(7, 10)));
    }

  //=====输出=======
  true
  true
  true
  false
  false

 

 

相关问答

更多
  • 你学电脑维修可以找个专业点的学校、我朋友也是学电脑维修的、不过是在深圳这边学习电脑维修培训课 程、他学的是主板维修课程和笔记本维修课程、是在一家叫红警电脑维修培训学校学习的、这所电脑维修 学校实力挺不错的、他学完后不外就找到一份不错的工作、听他说这所电脑维修培训学校还可以推荐就业 、而且教学也主要是以实操为主的呢、
  • 下载个金山打字软件安装上,就可以按步骤循序渐进的学习了。五笔、拼音、词语、句子、文章等等都能练习。
  • jstat(JVM Statistics Monitoring Tool)是用于监控虚拟机各种运行状态信息的命令行工具。他可以显示本地或远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据,在没有GUI图形的服务器上,它是运行期定位虚拟机性能问题的首选工具。 jstat位于java的bin目录下,主要利用JVM内建的指令对Java应用程序的资源和性能进行实时的命令行的监控,包括了对Heap size和垃圾回收状况的监控。可见,Jstat是轻量级的、专门针对JVM的工具,非常适用。 jstat 命令 ...
  • java学习笔记[2023-06-21]

    大家的笔记 http://student.csdn.net/space.php?do=blog 牛人的笔记 http://lavasoft.blog.51cto.com/all/62575 我的笔记 http://student.csdn.net/space.php?uid=209919&do=blog&view=me
  • 我想这就是你要找的东西 public static final Function, Range> DURATION_RANGE_TO_LONG_RANGE = new Function, Range>() { @Override public Range apply(final Range input) { return Range.range(inpu ...
  • 在这个特定的例子中,你最好不要使用Range ,而是直接使用set.subSet(4, true, 10, true) ,但大概你有一个更复杂的用例,你的代码是一个简单的例子。 除了自己处理所有情况外,没有其他选择。 部分问题是NavigableSet可以使用任意Comparator ,但Range (有意)仅适用于值类型的自然顺序,所以在Guava中提供一个采用任意Range和a的方法会有些尴尬NavigableSet并将它们相交。 最一般的解决方案看起来像... if (range.hasLowerBo ...
  • Guava的Range仅需要其封闭类型中的一个:它们实现Comparable 。 但并非所有实现Comparable都有距离概念。 例如,你如何测量两个String之间的距离? 这就是为什么Guava还有DiscreteDomain和ContiguousSet ; 对于前者,你有像next() , prev()和distance() ,这是你在这里感兴趣的。 Guava的网站上有一篇文章 。 Guava's Range only require one thing of its enclosed types ...
  • Patterns.containsPattern用@GwtIncompatible注释,这意味着它不在guava-gwt中。 顺便说一下,你应该为guava-gwt和番石榴使用相同的版本。 Patterns.containsPattern is annotated with @GwtIncompatible which means it's not in guava-gwt. BTW, you should use the same version for guava-gwt and guava.
  • 如果您阅读Range的javadoc: 请注意,无法迭代这些包含的值。 为此,请将此范围实例和相应的DiscreteDomain传递给ContiguousSet.create(com.google.common.collect.Range, com.google.common.collect.DiscreteDomain) 。 所以你的方法是正确的,除了你需要为自定义对象创建一个自定义DiscreteDomain : public class CustomDiscreteDomain exten ...