這將是一個系列的文字,用來擴展我們對於自定義Range類的使用思路。也許我們在Groovy語言的編碼不知不覺的使用到了Range類,甚至沒有覺察到它的存在;或者我們在Groovy語言的編碼過程中,常常驚歎於使用Range類的方便,但僅僅是驚歎而已,我們沒有付之行動;或者我們想在實際編碼中使用自定義的Range類,但卻找不到使用它的適當地方。等等,所有這些,希望在讀完我們的這個系列後,我們能夠將被動的使用Range類,轉化為主動的使用我們自定義的Range類。
Groovy語言引入的一個重要概念就是Range。有了Range,我們可以寫出形如下面的樣子的代碼來:
(1..10).each{
print it
}
println ''
運行結果為:
12345678910
我們在Groovy語言的代碼中,到處都可以找到Range的身影。使用起來非常的方便,在這裡我們就不多說了。
Groovy語言除了給我們引入了Range的概念,還有一個革新之處是我們可以自定義Range。能夠自定義Range類,我們肯定是歡迎的,因為在初始化一個集合類對象的時候,我們使用List或數組,需要把它們的所有元素都實例化出來,然後放到容器裡;而我們在使用Range的時候,只需要實例化首尾兩個元素,就可以獲取到集合類對象。當然是極大的方便了我們。
多說無憑,我們還是先來看看一個自定義Range類的例子吧。
這個例子說的是,一個部門有五個科室,我們需要遍歷所有科室的情況。
要自定義一個Range類,我們要做的工作首先是讓這個類實現"Comparable"接口,然後在該類裡依次實現"next"、"previous"和"compareTo"方法即可。當然,這些方法都是Range類對象用來遍歷用的,非實現不可。
現在來看我們自定義的科室代碼:
class Section implements Comparable{
def SECTION_TYPE = ['Yike','Erke','Sanke','Sike','Wuke']
private index = 0
public Section(type)
{
this.index = SECTION_TYPE.indexOf(type)
}
Section next()
{
new Section(SECTION_TYPE[(index+1)%SECTION_TYPE.size()])
}
Section previous()
{
new Section(index-1)
}
int compareTo(Object other)
{
index<=>other.index
}
public String toString()
{
SECTION_TYPE[index]
}
}
整個類也十分的簡單,"SECTION_TYPE"用來定義科室的代碼,以便Range類對象能夠自動實例化一個科室。
"index"變量是用來在遍歷時確定位置的。
"next"方法是用來往後遍歷,"previous"方法是用來往前遍歷,"compareTo"方法用來比較兩個元素的位置。這都是Range類必須實現的方法。
在所有的自定義Range類中,它們的實現邏輯都大同小異。
而"toString"方法才是科室類自己的方法,當然,我們可以在科室類裡定義很多科室類要用到的其他方法,在本例中,為了簡單起見,就不再多定義其他方法了。
下面,我們就可以來測試這個自定義的Range類了:
def yike = new Section('Yike')
def wuke = new Section('Wuke')
(yike..wuke).each{
println it.toString()
}
運行的結果為:
Yike
Erke
Sanke
Sike
Wuke
我們再回過頭來看測試代碼,在代碼中,我們只初始化了兩個科室對象,如下所示:
def yike = new Section('Yike')
def wuke = new Section('Wuke')
就可以進行五個對象的遍歷了。如果我們使用List對象,那麼代碼將是下面的這個樣子的:
def list = [new Section('Yike'),
new Section('Erke'),
new Section('Sanke'),
new Section('Sike'),
new Section('Wuke')]
list.each{
println it.toString()
}
這個很簡單的例子當然初步的顯示了自定義Range類的優越性,但是自定義的Range類絕不止這麼簡單,它還有更為廣闊的舞台。
這將是本系列文字的下一個部分將要說到的。