Lists
你能使用下面的方法创建一个lists,注意[]是一个空list。
1 |
def list = [ 5 , 6 , 7 , 8 ] |
2 |
assert list. get ( 2 ) == 7 |
3 |
assert list[ 2 ] == 7 |
4 |
assert list instanceof java.util.List |
5 |
6 |
def emptyList = [] |
7 |
assert emptyList. size () == 0 |
8 |
emptyList.add( 5 ) |
9 |
assert emptyList. size () == 1 |
每个列表表达式都是创建了 java.util.List的一个实例。
Ranges
Ranges容许你创建一个值序列,这个只序列可以被用作Lists,因为Range继承自Java.util.List.
Ranges 使用 ..来定义,并且包含两端的值
Ranges 也可以使用 ..< 来定义半开闭序列,这样创建的序列将包含最左边的,但是不包含最右边的:
1 |
// an inclusive range |
2 |
def range = 5 .. 8 |
3 |
assert range. size () == 4 |
4 |
assert range. get ( 2 ) == 7 |
5 |
assert range[ 2 ] == 7 |
6 |
assert range instanceof java.util.List |
7 |
assert range. contains ( 5 ) |
8 |
assert range. contains ( 8 ) |
9 |
10 |
// lets use a half-open range |
11 |
range = 5 ..< 8 |
12 |
assert range. size () == 3 |
13 |
assert range. get ( 2 ) == 7 |
14 |
assert range[ 2 ] == 7 |
15 |
assert range instanceof java.util.List |
16 |
assert range. contains ( 5 ) |
17 |
assert ! range. contains ( 8 ) |
18 |
19 |
//get the end points of the range without using indexes |
20 |
def range = 1 .. 10 |
21 |
assert range.from == 1 |
22 |
assert range.to == 10 |
Ranges适用于任何的实现了 java.lang.Comparable接口的Java对象,而且他也有next()和 previous() 方法来访问下一个和上一个元素。
比如你可以在Ranges中是用String:
1 |
// an inclusive range |
2 |
def range = 'a' .. 'd' |
3 |
assert range. size () == 4 |
4 |
assert range. get ( 2 ) == 'c' |
5 |
assert range[ 2 ] == 'c' |
6 |
assert range instanceof java.util.List |
7 |
assert range. contains ( 'a' ) |
8 |
assert range. contains ( 'd' ) |
9 |
assert ! range. contains ( 'e' ) |
Ranges可以和for循环结合起来说使用:
1 |
for (i in 1 .. 10 ) { |
2 |
println "Hello ${i}" |
3 |
} |
使用下面的代码也可以达到上述的效果:
1 |
( 1 .. 10 ). each { i -> |
2 |
println "Hello ${i}" |
3 |
} |
Ranges当然也可以用在switch中:
1 |
switch (years) { |
2 |
case 1 .. 10 : interestRate = 0.076 ; break ; |
3 |
case 11 .. 25 : interestRate = 0.052 ; break ; |
4 |
default : interestRate = 0.037 ; |
5 |
} |
Maps
注意 [:] 其实是一个空的Map。
Map的key如果是string的话,默认是这种形式: [a:1],它等价于["a":1]. 但是如果你真的想让一个变量作为key的话,那么你必须使用括号将他包起来: [(a):1].
1 |
def map = [name: "Gromit" , likes: "cheese" , id: 1234 ] |
2 |
assert map. get ( "name" ) == "Gromit" |
3 |
assert map. get ( "id" ) == 1234 |
4 |
assert map[ "name" ] == "Gromit" |
5 |
assert map[ 'id' ] == 1234 |
6 |
assert map instanceof java.util.Map |
7 |
8 |
def emptyMap = [:] |
9 |
assert emptyMap. size () == 0 |
10 |
emptyMap.put( "foo" , 5 ) |
11 |
assert emptyMap. size () == 1 |
12 |
assert emptyMap. get ( "foo" ) == 5 |
Maps也有点想beans,这样就可以使用.号来获取属性:
1 |
def map = [name: "Gromit" , likes: "cheese" , id: 1234 ] |
2 |
assert map.name == "Gromit" |
3 |
assert map.id == 1234 |
4 |
5 |
def emptyMap = [:] |
6 |
assert emptyMap. size () == 0 |
7 |
emptyMap.foo = 5 |
8 |
assert emptyMap. size () == 1 |
9 |
assert emptyMap.foo == 5 |
更有效的使用’*.’操作符
我们可以使用这个操作符来操作集合中的所有元素:
1 |
assert [ 1 , 3 , 5 ] == [ 'a' , 'few' , 'words' ]*. size () |
增强的集合方法:
比如下面的例子:
1 |
def words = [ 'ant' , 'buffalo' , 'cat' , 'dinosaur' ] |
2 |
assert words. findAll { w -> w. size () > 4 } == [ 'buffalo' , 'dinosaur' ] |
下面的这个例子获取了所有元素的首字母:
1 |
def words = [ 'ant' , 'buffalo' , 'cat' , 'dinosaur' ] |
2 |
assert words. collect { it[ 0 ] } == [ 'a' , 'b' , 'c' , 'd' ] |
切片操作符
1 |
def text = "nice cheese gromit!" |
2 |
def x = text[ 2 ] |
3 |
4 |
assert x == "c" |
5 |
assert x. class == String |
6 |
7 |
def sub = text[ 5 .. 10 ] |
8 |
assert sub == 'cheese' |
9 |
10 |
def map = [name: "Gromit" , likes: "cheese" , id: 1234 ] |
11 |
12 |
assert map[ "name" ] == "Gromit" |
13 |
assert map.name == "Gromit" |
14 |
15 |
def list = [ 10 , 11 , 12 ] |
16 |
def answer = list[ 2 ] |
17 |
assert answer == 12 |
下面再给出一些例子:
1 |
def list = 100 .. 200 |
2 |
def sub = list[ 1 , 3 , 20 .. 25 , 33 ] |
3 |
assert sub == [ 101 , 103 , 120 , 121 , 122 , 123 , 124 , 125 , 133 ] |
也可以使用切片操作符来更新元素
1 |
def list = [ "a" , "b" , "c" ] |
2 |
list[ 2 ] = "d" |
3 |
list[ 0 ] = list[ 1 ] |
4 |
list[ 3 ] = 5 |
5 |
assert list == [ "b" , "b" , "d" , 5 ] |
我们可以使用负数来从尾部获取 List, array, String 等的值:
1 |
def text = "nice cheese gromit!" |
2 |
def x = text[- 1 ] |
3 |
assert x == "!" |
4 |
5 |
def name = text[- 7 ..- 2 ] |
6 |
assert name == "gromit" |
如果你使用一个向后的索引,也就是说前面的值比后面的大,比如[3:1],那么得到的结果是相反的:
1 |
def text = "nice cheese gromit!" |
2 |
def name = text[ 3 .. 1 ] |
3 |
assert name == "eci" |
Dynamic objects (Expandos)
Expando 在严格意义上来说并不是一个集合。但是有点类似于Map, .他容许你充分理由Groovy’s closure mechanisms来创建动态对象, 但是 Expando和Map不同的是他可以提供 synthetic methods 。
1 |
def player = new Expando() |
2 |
player.name = "Dierk" |
3 |
player.greeting = { "Hello, my name is $name" } |
4 |
5 |
println player.greeting() |
6 |
player.name = "Jochen" |
7 |
println player.greeting() |
The player.greeting assignment passes in a closure to execute when greeting() is called on the Expando. Notice that the closure has access to the properties assigned to the Expando, even though these values may change over time, using Groovy’s GString ”$variableOrProperty” notation.