在Guava中新增了一個新的類型Range,從名字就能夠了解到,這個是和區間有關的數據結構。從Google官方文檔能夠獲得定 義:Range定義了連續跨度的範圍邊界,這個連續跨度是一個能夠比較的類型(Comparable type)。好比1到100之間的整型數據。數據結構
在數學裏面的範圍是有邊界和無邊界之分的;一樣,在Guava中也有這個說法。若是這個範圍是有邊界的,那麼這個範圍又能夠分爲包括開集(不包括端點)和閉集(包括端點);若是是無解的能夠用+∞表示。若是枚舉的話,一共有九種範圍表示:less
Guava Range 概念,範圍和方法 spa
概念 | 表示範圍 | 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時須要注意:在構造區間時,儘可能使用不可改變的類型。若是你須要使用可變的類型,在區間類型構造完成的狀況下,請不要改變區間兩邊的數。code
實例:文檔
"open:"+Range.open(1, 10"closed:"+ Range.closed(1, 10"closedOpen:"+ Range.closedOpen(1, 10"openClosed:"+ Range.openClosed(1, 10"greaterThan:"+ Range.greaterThan(10"atLeast:"+ Range.atLeast(10"lessThan:"+ Range.lessThan(10"atMost:"+ Range.atMost(10"all:"+"closed:"+Range.closed(10, 10"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)); } }
輸出:io
downTo:(4‥+∞) upTo:(-∞‥4] range:[1‥4)
操做方法table
1.contains:判斷值是否在當前Range內ast
@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相關查詢方法:class
@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