原文連結 譯文連結 譯者:jackwang
groovy提供了各種類型的原生态集合支援,包括list, maps 和 ranges 。它們大多數都是基于java集合類型,同時在java集合類型中一些廢棄的方法在groovy開發套件中也可以找到。
注:譯者也是第一次接觸groovy,由于時間和水準有限(姑且讓譯者使用這個理由吧,對待知識本應該一絲不苟)部分專有名詞可能翻譯不準确甚至有誤(讀者閱讀的過程中最好能參考原文),懇請讀者不吝留言指出,謝謝!
(譯者注:原文是list literals,直譯可以翻譯為list字面意思,從下文内容來看指的就是list建立和擷取元素,譯者意譯為list基本用法)
你可以使用如下方式建立一個list,注意[]是一個空list表達式。
每一個list表達式都是java.util.list的一個實作。
當然,lists也可以用于構造另外一個list:
list是一個序列集合的對象(譯者注:原文是a list is an ordered collection of objects,從下文的示例代碼來看,這裡不是有序的意思,而是相當于java集合裡的arraylist,是以認為翻譯為序列比有序更為恰當):
list可以當作一個boolean值:
疊代一個list上的元素可以使用each和eachwithindex方法,示例代碼如下:
除了上面的用法,通過使用疊代,還可以将某些元素轉換為另外一種元素來建立一個新的集合。這也是非常有用的用法。這樣的操作,通常叫做映射。在groovy裡可以使用collect方法:
過濾和搜尋
groovy開發套件在集合操作上提供了許多方法來拓展标準集合,一些方法示例如下:
下面是使用groovy在集合中查找最大最小值的标準代碼:
除了使用閉包,你可以使用comparator來定義一個比較:
添加或删除元素
我們可以使用[]來建立一個新的空list,使用<<來追加元素在裡面:
我們也可以使用下面的方法來添加元素:
特别重要的是+操作不能改變一個集合。和<<相比,它會建立一個新的list,這可能通常不是你想要的結果,同時會有性能問題。(譯者注:這裡和java中string類型的+操作類似)
groovy開發套件提供了下面的方法來輕松實作從集合中删除元素:
也可以使用下标操作來删除元素,這樣會使原集合發生改變:
有時候你僅僅想删除第一次出現的元素,而不是删除全部比對的元素,你可以這樣是使用remove方法:
清空一個list可以使用clear方法:
set操作
groovy開發套件同樣也提供了許多方法來友善進行sets操作
排序
使用collections的排序,groovy提供了許多參數來排序一個lists,從使用閉包到使用比較器,示例代碼如下:
複制元素
groovy開發套件重載了一些操作來對集合進行複制操作:
在groovy裡,maps(通常和arrays聯系在一起)可以使用 [:] 來建立:
map的key預設是字元串類型的,[a:1]和[‘a’:1]是等效的。如果你的變量名字恰好也是a 那就會導緻混亂了,可能你是想将 a 的值作為你map的key。如果是這種情況,你必須使用括号來轉義,類似下面的例子:
除了map的基本操作,要得到一個map的新的拷貝,可以clone它:
上面的例子得到的就是原始map的一個投影。
maps可以像你操作bean那樣通過使用屬性标記來get/set map内部的元素。隻要key是groovy識别的字元串:
注意:預設情況下map.foo将總是在map中搜尋key為foo的元素。這意味着如果一個map鐘不含有class的可以,foo.class将會傳回null。如果你隻是想知道類類型,你必須使用getclass() :
通常在groovy開發套件裡,疊代map是用each和eachwithindex方法。maps的建立也是序列的,也就是說當你疊代一個map的時候,可以保證疊代的順序就是添加元素的順序:
添加一個元素到map可以使用put,批量操作可以使用putall:
删除一個map鐘全部元素可以使用clear方法:
使用map基本操作生成的map使用了對象的equals和hashcode方法。這個意味着你不應該使用一個hash code經常改變的對象或者其值不可逆操作的對象放入map。
你使用一個gstring來作為map的key也是沒有意義的。因為gstring的hashcode和string的hashcode并不相等。
keys,values和entries
我們可以在一個視圖裡檢視keys,values和entries:
通過視圖(也就是map的key,entry和value)傳回的值來操作values是強烈不推薦的方式。因為maps操作已經有很多直接操作的方法。特别地,groovy依賴于jdk的一些方法并不保證能夠安全地操作集合,比如keyset,entryset或values
groovy開發套件包含過濾,搜尋集合方法,這個和list是類似的:
分組
我們可以将一個list按某些次元分組到一個map中:
ranges允許你建立一個序列值得list,它可以當成list用,因為range繼承了java.util.list
ranges定義使用 .. 代表閉區間(包括起點和終點)
ranges定義使用 ..< 代表一個半開半閉,隻包含第一個值不包含最後一個值。
可以看到建立一個int區間是非常高效的,可以建立一個非常輕量級的包含起點值和終點值得對象。
區間也可以用作實作了java.lang.comparable接口作為比較器的任何java對象。可以使用next()和previous()來傳回netx/previous元素。舉個例子,你可以建立一個string元素類型的區間:
你可以使用for循環來疊代區間元素:
當然你也可以使用更加groovy風格的方式來實作同樣的效果,通過使用each方法來疊代區間元素:
區間同樣可以用在switch語句中:
幸虧屬性标記對lists和maps都支援,groovy 提供了非常實用的方法來使嵌套集合處理變得非常簡潔,示例代碼如下:
spread操作可以認為是将一個集合内聯到另外一個集合。這樣就可以避免使用putall方法進而将實作變得隻要一行代碼:
星号操作是允許你在一個集合的全部元素中調用某個方法或屬性的簡潔操作:
你可以使用下标來索引lists,arrays,maps。字元串類型被當成一種特殊的集合類型:
注意你可以使用區間來提取集合:
下标操作也可以用于更新已有集合(對于那些不可變集合)
值得注意的是負數也是被允許的,表示從集合後面提取元素:你可以使用負數來表示從尾開始操作list,array,string等:
同樣地,如果你使用一個反向區間(起點下标大于終點下标),結果也會是反的。
對于list, maps和ranges,groovy提供了許多額外的方法來過濾,集合分組,技術等等,那些方法使集合操作更加簡單,疊代操作更加容易。
特别地,我們希望你能特别地讀一下groovy開發套件的api文檔:
iterable額外的方法可以在這裡找到
iterator額外的方法可以在這裡找到
collection額外的方法可以在這裡找到
list額外的方法可以在這裡找到
map額外的方法可以在這裡找到
configslurper是用來讀配置檔案的工具類,通常是grooy腳本格式的配置檔案。類似于java裡的*.properties檔案。configslurper允許點操作符,除此之外,還允許閉包操作配置值和一些對象類型
(1)使用點操作符
(2)使用閉包來代替點操作符
從上面的例子可以看到,parse方法可以用來傳回groovy.util.configobject執行個體,configobject是一種特别的java.util.map實作。既可以用于傳回配置值,也可以傳回一個不為null的新的configobject執行個體對象
(1)config.test還沒有被執行個體化是以當被調用的時候将會傳回一個configobject
如果點号是配置檔案值的一部分,可以使用單引号或雙引号将其轉義。
除此之外,configslurper也支援environments . enviroments方法可以被用來處理閉包執行個體,它自身也有可能由好幾個部分組成。假如說我們想建立一個特定的配置值來給開發環境用,當我們建立一個configslurper執行個體的時候我們可以使用configslurper(string)構造函數來實作特定環境的配置.
configslurper環境變量沒有嚴格遵循任何環境變量名字。取決于特定的configslurper用戶端代碼。
enviroments方法是一個那隻方法,但是registerconditionalblock方法可以用于注冊其他方法名字,并且可以是enviroments名字。
(1)一旦一個新的塊注冊了,configslurper可以編碼它
因為java內建原因,toproperties方法可以用于将configobject對象轉換到java.util.properties對象。然後可以将其存在*.properties文本檔案中。注意,在建立一個properties執行個體的時候配置值将會轉換為string類型執行個體。
expando類可以用于動态建立可拓展對象。盡管它的類名沒有采用expandometaclass。每一個expando對象代表一個獨立的動态的執行個體,可以在運作時被屬性或方法所拓展
一個特殊的例子是當一個動态屬性注冊到一個閉包代碼塊。一個注冊就可以被方法所動态調用:
groovy提供了可觀察的lists,maps和sets。每一個都是一個java.beans.propertychangeevnent事件的觸發器。當元素被添加,删除,修改就會被觸發。注意propertychangeevent不僅僅當某些事件發生才出發,同時可以儲存新舊值。
可能會有類型改變,可觀察的集合可能需要更加特别的propertychangeevnet類型。比如當添加一個元素到可觀察list觸發一個observablelist.elementaddedevent事件。
(1)聲明一個propertychangeeventlistener可以捕捉觸發事件
(2)observablelist.elementevent和它的相關類型是相對與這個監聽器
(3)注冊一個監聽器
(4)從給定的list建立一個observablelist
(5)observablelist.elementaddedevent事件的觸發器
注意,添加一個元素将會觸發兩個事件,第一個是observablelist.elementaddedevent 第二個是 propertychangeevent,用來通知監聽器這次修改屬性的size
observablelist.elementclearedevent 事件類型是另外一個有趣的事件。無論什麼時候多個元素被删除,比如當我們調用clear()方法的時候,它将會儲存被删除的元素
為了了解整個事件類型,建議讀者閱讀javadoc文檔或可觀察集合的源碼。
這個章節裡,observablemap和observableset是同一個概念,和我們見過的observablelist一樣。