數學裏的區間可以描述一個範圍,guava中使用Range幫助我們實現了這種功能。
主要方法如下:
離散區間抽象類:DiscreteDomain,可以自己實現這個抽象類來創建特定的離散類。
代碼示例:
RangeTest 類
package com.bluedragon.guavalearning.range;
import com.google.common.collect.BoundType;
import com.google.common.collect.ContiguousSet;
import com.google.common.collect.DiscreteDomain;
import com.google.common.collect.Range;
/**
* @author CodeRush
* @date 2019/8/14 23:49
*/
public class RangeTest {
public static void main(String[] args) {
//創建一個空的開區間集合
Range<Integer> open = Range.open(0, 1);
Range<Integer> emptyRange = Range.closedOpen(5, 5);
boolean empty = open.isEmpty();
System.out.println(emptyRange.isEmpty());
//是否爲空集合
System.out.println(empty);
//是否包含
boolean contains = open.contains(0);
System.out.println(contains);
//是否有下界
boolean hasLowerBound = open.hasLowerBound();
System.out.println(hasLowerBound);
//是否有上界
boolean hasUpperBound = open.hasUpperBound();
System.out.println(hasUpperBound);
//下界類型:CLOSED/OPEN 閉/開
System.out.println(open.lowerBoundType());
//上界類型
System.out.println(open.upperBoundType());
//下界值
System.out.println(open.lowerEndpoint());
//上界值
System.out.println(open.upperEndpoint());
Range<Integer> openTemp = Range.open(0, 3);
System.out.println(openTemp.contains(1));
try {
Range<Integer> open2 = Range.open(0, 0);
} catch (IllegalArgumentException e) {
System.out.println("創建參數錯誤");
}
//閉區間
Range<Integer> closed = Range.closed(1, 5);
System.out.println(closed.lowerBoundType());
System.out.println(closed.upperBoundType());
System.out.println(closed.lowerEndpoint());
System.out.println(closed.upperEndpoint());
//左開右閉
Range<Integer> openClosed = Range.openClosed(3, 10);
System.out.println(openClosed);
//左閉右開
Range<Integer> closedOpen = Range.closedOpen(-5, 2);
System.out.println(closedOpen);
//最小(包含)-正無窮
Range<Integer> atLeast = Range.atLeast(-1);
System.out.println(atLeast);
//負無窮-最大(包含)
Range<Integer> atMost = Range.atMost(100);
System.out.println(atMost);
//負無窮-此值(小於說明不包含)
Range<Integer> lessThan = Range.lessThan(99);
System.out.println(lessThan);
//此值(大於說明不包含)-正無窮
Range<Integer> greaterThan = Range.greaterThan(0);
System.out.println(greaterThan);
//負無窮-正無窮
Range<Comparable<?>> all = Range.all();
System.out.println(all);
//負無窮-上限(開閉自己指定)
Range<Integer> upTo = Range.upTo(10, BoundType.CLOSED);
System.out.println(upTo);
//下限(開閉自己指定)-正無窮
Range<Integer> downTo = Range.downTo(1, BoundType.OPEN);
System.out.println(downTo);
//只包含一個元素的區間,左右都是閉合的,單值區間
Range<Integer> singleton = Range.singleton(1);
System.out.println(singleton);
//上下界及開閉都自己指定
Range<Double> range = Range.range(1.0, BoundType.CLOSED, 123.22, BoundType.OPEN);
System.out.println(range);
/**交、並**/
Range<Integer> open1 = Range.open(-1, 1);
Range<Integer> closed1 = Range.closed(10, 15);
Range<Integer> openClosed1 = Range.openClosed(-1, 11);
Range<Integer> closedOpen1 = Range.closedOpen(0, 9);
//區間是否包含了某區間
System.out.println(open1.encloses(closed1));
System.out.println(openClosed1.encloses(open1));
System.out.println(closedOpen1.encloses(open1));
//交集,如果沒有交集會拋出非法參數異常
try {
Range<Integer> intersection = open1.intersection(closed1);
System.out.println(intersection);
} catch (IllegalArgumentException e) {
System.out.println("沒有交集,拋出非法參數異常");
}
Range<Integer> intersection1 = closed1.intersection(openClosed1);
System.out.println(intersection1);
//返回”同時包括兩個區間的最小區間”,如果兩個區間相連,那就是它們的並集。
Range<Integer> span = open1.span(openClosed1);
System.out.println(span);
Range<Integer> span1 = closed1.span(openClosed1);
System.out.println(span1);
//判斷是否有區間同時位於這兩個區間之間->是否有交集
System.out.println(open1.isConnected(closed1));
System.out.println(open1.isConnected(openClosed1));
System.out.println(Range.open(1, 2).isConnected(Range.open(2, 3)));
//離散域
System.out.println("=================離散域=================");
DiscreteDomain<Integer> integers = DiscreteDomain.integers();
//離散域中兩個元素的距離
System.out.println(integers.distance(0, 10));
//離散域上界
System.out.println(integers.maxValue());
//離散域下界
System.out.println(integers.minValue());
//某個元素下一個
System.out.println(integers.next(0));
//某個元素上一個
System.out.println(integers.previous(0));
ContiguousSet<Integer> integerContiguousSet = ContiguousSet.create(Range.open(1, 9), integers);
Range<Integer> integerRange = integerContiguousSet.range();
System.out.println(integerRange);//[2‥8]
System.out.println(integerContiguousSet.headSet(5).range());//[2‥4]
System.out.println(integerContiguousSet.tailSet(5).range());//[5‥8]
//自定義離散域
EvenIntegerDiscreteDomain evenIntegerDiscreteDomain = new EvenIntegerDiscreteDomain(0, 100);
System.out.println(String.format("next(5):%s,netx(4):%s,next(3):%s", evenIntegerDiscreteDomain.next(5),
evenIntegerDiscreteDomain.next(4), evenIntegerDiscreteDomain.next(3)));
System.out.println(String.format("previous(5):%s,previous(4):%s,previous(3):%s", evenIntegerDiscreteDomain.previous(5),
evenIntegerDiscreteDomain.previous(4), evenIntegerDiscreteDomain.previous(3)));
System.out.println(String.format("max:%s,min:%s", evenIntegerDiscreteDomain.maxValue(), evenIntegerDiscreteDomain.minValue()));
System.out.println(String.format("evenIntegerDiscreteDomain.distance(3, 5):%s", evenIntegerDiscreteDomain.distance(3, 5)));
System.out.println(String.format("evenIntegerDiscreteDomain.distance(3, 6):%s", evenIntegerDiscreteDomain.distance(3, 6)));
}
}
自己實現的偶數離散類EvenIntegerDiscreteDomain
package com.bluedragon.guavalearning.range;
import com.google.common.collect.DiscreteDomain;
public class EvenIntegerDiscreteDomain extends DiscreteDomain<Integer> {
private Integer min;
private Integer max;
public EvenIntegerDiscreteDomain(int min, int max) {
min = min % 2 == 0 ? min : min - 1;
max = max % 2 == 0 ? max : max - 1;
this.min=min;
this.max=max;
}
@Override
public Integer next(Integer referValue) {
int referEvenValue = referValue % 2 == 0 ? referValue : referValue - 1;
int next = referEvenValue + 2;
next = next > this.max ? this.max : next;
return next;
}
@Override
public Integer previous(Integer referValue) {
int referEvenValue = referValue % 2 == 0 ? referValue : referValue - 1;
int previous = referEvenValue - 2;
previous = previous < this.min ? this.min : previous;
return previous;
}
@Override
public long distance(Integer first, Integer second) {
first = first % 2 == 0 ? first : first - 1;
second = second % 2 == 0 ? second : second - 1;
return (second - first) / 2;
}
@Override
public Integer minValue() {
return this.min;
}
@Override
public Integer maxValue() {
return this.max;
}
}
輸出結果:
true
false
false
true
true
OPEN
OPEN
0
1
true
創建參數錯誤
CLOSED
CLOSED
1
5
(3‥10]
[-5‥2)
[-1‥+∞)
(-∞‥100]
(-∞‥99)
(0‥+∞)
(-∞‥+∞)
(-∞‥10]
(1‥+∞)
[1‥1]
[1.0‥123.22)
false
true
false
沒有交集,拋出非法參數異常
[10‥11]
(-1‥11]
(-1‥15]
false
true
false
=================離散域=================
10
2147483647
-2147483648
1
-1
[2‥8]
[2‥4]
[5‥8]
next(5):6,netx(4):6,next(3):4
previous(5):2,previous(4):2,previous(3):0
max:100,min:0
evenIntegerDiscreteDomain.distance(3, 5):1
evenIntegerDiscreteDomain.distance(3, 6):2