目录
【区间】
第二章 提到的RangeSet中有用到 Range区间工具,现在就这里详细了解下。Range就是指所谓的区间,仅支持传入所有实现 Comparable接口的类型,但支持多种区间的定义、计算等操作。
一、构建区间
由于 Range的构造器被声明为私有类型,因此初始化实例都是通过静态方法实现。
静态方法 | 区间类型 |
---|---|
open(C, C) | (a, b) |
closed(C, C) | [a, b] |
closedOpen(C, C) | [a, b) |
openClosed(C, C) | (a, b] |
greaterThan(C ) | (a, +∞) |
atLeast(C ) | [a, +∞) |
lessThan(C ) | (-∞, a) |
atMost(C ) | (-∞, a] |
all() | (-∞, +∞) |
range(C, BoundType, C, BoundType) | 有界区间 |
downTo(C, BoundType) | (a, +∞)或[a, -∞) |
upTo(C, BoundType) | (-∞, a)或(-∞, a] |
BoundType是一个枚举类型,包含CLOSED和OPEN两个值。
二、区间运算
Range<Integer> range = Range.downTo(1, BoundType.OPEN);
range.contains(2); // true
range.containsAll(Ints.asList(1,2,3)); // false
range.hasLowerBound(); // true
range.hasUpperBound(); // false
range.lowerBoundType(); // OPEN
// range.upperBoundType(); // throw IllegalStateException
range.lowerEndpoint(); // 1
// range.upperEndpoint(); // throw IllegalStateException
range.isEmpty(); // false
range.encloses(Range.atLeast(1)); // false
range.isConnected(Range.atMost(1)); // true
range.intersection(Range.closed(0, 4)); // (1‥4]
range.span(Range.open(-1, 0)); // (-1‥+∞)
方法名 | 说明 |
---|---|
boolean contains(C ) | 区间内是否包含某个值 |
boolean containsAll(Iterable) | 区间内是否包含多个值 |
boolean hasLowerBound() | 区间是否有下界 |
boolean hasUpperBound() | 区间是否有上界 |
BoundType lowerBoundType() | 区间下界类型,若无下界,抛出IllegalStateException |
BoundType upperBoundType() | 区间上界类型,若无上界,抛出IllegalStateException |
Integer lowerEndpoint() | 区间下界的端点值,若无下界,抛出IllegalStateException |
Integer upperEndpoint() | 区间上界的端点值,若无上界,抛出IllegalStateException |
boolean isEmpty() | 区间是否为空 |
boolean encloses(Range) | 是否包含给定区间 |
boolean isConnected(Range) | 是否与给定区间相连 |
Range intersection(Range) | 返回两区间的交集 |
Range span(Range) | 返回”同时包括两个区间的最小区间” |
三、离散域(个人感觉不太常用)
部分(但不是全部)可比较类型是离散的,即区间的上下边界都是可枚举的。
Guava用DiscreteDomain实现类型C的离散形式操作。一个离散域总是代表某种类型值的全集;它不能代表类似”素数”、”时间戳”等这样的局部域。
目前 DiscreteDomain提供的离散域实例包括:
类型 | 离散域 |
---|---|
Integer | integers() |
Long | Longs() |
BigInteger | bigIntegers() |
一旦获取了DiscreteDomain实例,就可以使用下面的Range运算方法:
● ContiguousSet.create(range, domain):用ImmutableSortedSet形式表示Range中符合离散域定义的元素,并增加一些额外操作;
● canonical(domain):把离散域转为区间的“规范形式”,所谓“规范形式”应该是指区间的“左闭右开”形式。
注:Range并没有提供基于 Comparator接口的方法,如需要可通过以下方法来处理
● Range实现了Predicate接口,因此可以用Predicates.compose(range, function)
● 使用包装类以定义期望的排序