Guava区间-Range

在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 valuesall()

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

示例

import com.google.common.collect.BoundType;
import com.google.common.collect.Range;
import com.google.common.primitives.Ints;
import org.junit.Test;

/**
 * Created by g on 2016/8/5.
 */
public class RangeTest {

    @Test
    public void rangeTest() {
        // open:(1‥10)
        System.out.println("open:" + Range.open(1, 10));
        // closed:[1‥10]
        System.out.println("closed:" + Range.closed(1, 10));
        // closedOpen:[1‥10)
        System.out.println("closedOpen:" + Range.closedOpen(1, 10));
        // openClosed:(1‥10]
        System.out.println("openClosed:" + Range.openClosed(1, 10));
        // greaterThan:(10‥+∞)
        System.out.println("greaterThan:" + Range.greaterThan(10));
        // atLeast:[10‥+∞)
        System.out.println("atLeast:" + Range.atLeast(10));
        // lessThan:(-∞‥10)
        System.out.println("lessThan:" + Range.lessThan(10));
        // atMost:(-∞‥10]
        System.out.println("atMost:" + Range.atMost(10));
        // all:(-∞‥+∞)
        System.out.println("all:" + Range.all());
        // closed:[10‥10]
        System.out.println("closed:" + Range.closed(10, 10));
        // closedOpen:[10‥10)
        System.out.println("closedOpen:" + Range.closedOpen(10, 10));
        // 会抛出异常
//        System.out.println("open:" + Range.open(10, 10));

        // downTo:(4‥+∞)
        System.out.println("downTo:" + Range.downTo(4, BoundType.OPEN));
        // upTo:(-∞‥4]
        System.out.println("upTo:" + Range.upTo(4, BoundType.CLOSED));
        // range:[1‥4)
        System.out.println("range:" + Range.range(1, BoundType.CLOSED, 4, BoundType.OPEN));
    }

    @Test
    public void containsTest() {
        // contains:判断值是否在当前Range内
        // true
        System.out.println(Range.closed(1, 3).contains(2));
        // false
        System.out.println(Range.closed(1, 3).contains(4));
        // false
        System.out.println(Range.lessThan(5).contains(5));
        // true
        System.out.println(Range.closed(1, 4).containsAll(Ints.asList(1, 2, 3)));
    }

    @Test
    public void queryTest() {
        // Endpoint相关查询方法
        // true
        System.out.println("hasLowerBound:" + Range.closedOpen(4, 4).hasLowerBound());
        // true
        System.out.println("hasUpperBound:" + Range.closedOpen(4, 4).hasUpperBound());
        // true
        System.out.println(Range.closedOpen(4, 4).isEmpty());
        // true
        System.out.println(Range.openClosed(4, 4).isEmpty());
        // false
        System.out.println(Range.closed(4, 4).isEmpty());
        // 3
        System.out.println(Range.closed(3, 10).lowerEndpoint());
        // 3
        System.out.println(Range.open(3, 10).lowerEndpoint());
        // 10
        System.out.println(Range.closed(3, 10).upperEndpoint());
        // 10
        System.out.println(Range.open(3, 10).upperEndpoint());
        // CLOSED
        System.out.println(Range.closed(3, 10).lowerBoundType());
        // OPEN
        System.out.println(Range.open(3, 10).upperBoundType());
    }

    @Test
    public void enclosesTest() {
        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);
        // encloses(Range range)中的range是否包含在需要比较的range中
        // rangeBase: (1‥4) Enclose:true rangeClose:[2‥3]
        System.out.println("rangeBase: " + rangeBase + " Enclose:" + rangeBase.encloses(rangeClose) + " rangeClose:" + rangeClose);
        // rangeBase: (1‥4) Enclose:true rangeClose:[2‥4)
        System.out.println("rangeBase: " + rangeBase + " Enclose:" + rangeBase.encloses(rangeCloseOpen) + " rangeCloseOpen:" + rangeCloseOpen);
        // rangeBase: (1‥4) Enclose:false rangeClose:[2‥5)
        System.out.println("rangeBase: " + rangeBase + " Enclose:" + rangeBase.encloses(rangeCloseOther) + " rangeCloseOther:" + rangeCloseOther);
    }

    @Test
    public void isConnectedTest() {
        // isConnected range是否可以连接上
        // true
        System.out.println(Range.closed(3, 5).isConnected(Range.open(5, 10)));
        // true
        System.out.println(Range.closed(0, 9).isConnected(Range.closed(3, 4)));
        // true
        System.out.println(Range.closed(0, 5).isConnected(Range.closed(3, 9)));
        // false
        System.out.println(Range.open(3, 5).isConnected(Range.open(5, 10)));
        // false
        System.out.println(Range.closed(1, 5).isConnected(Range.closed(6, 10)));
    }

    @Test
    public void intersectionTest() {
        // intersection:如果两个range相连时,返回最大交集,如果不相连时,直接抛出异常
        // (5‥5]
        System.out.println(Range.closed(3, 5).intersection(Range.open(5, 10)));
        // [3‥4]
        System.out.println(Range.closed(0, 9).intersection(Range.closed(3, 4)));
        // [3‥5]
        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)));
    }

    @Test
    public void spanTest() {
        // span:获取两个range的并集,如果两个range是两连的,则是其最小range
        // [3‥10)
        System.out.println(Range.closed(3, 5).span(Range.open(5, 10)));
        // [0‥9]
        System.out.println(Range.closed(0, 9).span(Range.closed(3, 4)));
        // [0‥9]
        System.out.println(Range.closed(0, 5).span(Range.closed(3, 9)));
        // (3‥10)
        System.out.println(Range.open(3, 5).span(Range.open(5, 10)));
        // [1‥10]
        System.out.println(Range.closed(1, 5).span(Range.closed(6, 10)));
        // [1‥10]
        System.out.println(Range.closed(1, 5).span(Range.closed(7, 10)));
    }
}

 

转载于:https://my.oschina.net/kevinair/blog/728059

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值