JavaGroovy学习之-Groovy Development Kit(GDK)-集合操作

Groovy学习目录-传送门

Groovy为种种集合类型提供native协助,包涵ListMapRanges
其中大多数基于Java集合类型,并运用Groovy开发包中提供的任何措施开展了装修。

Lists

List 字面值

你可以按如下所示创立列表。 请注意,[]是空列表表明式。

def list = [5, 6, 7, 8]
assert list.get(2) == 7
assert list[2] == 7
assert list instanceof java.util.List

def emptyList = []
assert emptyList.size() == 0
emptyList.add(5)
assert emptyList.size() == 1

每一种列表表明式都以创建java.util.List的实例。

自然,二个list可以用作构造另多少个list的源:

def list1 = ['a', 'b', 'c']
//构造一个新的List,这个List和list1有相同的items
def list2 = new ArrayList<String>(list1)

assert list2 == list1 // == 检测每一个对应的item,判断它们是否相同

// clone() 也是可以使用的
def list3 = list1.clone()
assert list3 == list1

list是objects的静止聚集:

def list = [5, 6, 7, 8]
assert list.size() == 4
assert list.getClass() == ArrayList     //所使用的列表的具体类型

assert list[2] == 7                     // 索引是从0开始的
assert list.getAt(2) == 7               // 同[]运算符
assert list.get(2) == 7                 // 替代方法
list[2] = 9
assert list == [5, 6, 9, 8,]           //结果通过

list.putAt(2, 10)                       //等效于 list[2] = 10
assert list == [5, 6, 10, 8]
assert list.set(2, 11) == 10            // 赋值并返回原值
assert list == [5, 6, 11, 8]

assert ['a', 1, 'a', 'a', 2.5, 2.5f, 2.5d, 'hello', 7g, null, 9 as byte]
//元素可以是不同类型; 允许重复
assert [1, 2, 3, 4, 5][-1] == 5             // 允许负数index,从list尾部开始计数
assert [1, 2, 3, 4, 5][-2] == 4
assert [1, 2, 3, 4, 5].getAt(-2) == 4       // getAt() 可以使用负数index
try {
    [1, 2, 3, 4, 5].get(-2)                 // 但是get()方法不允许使用负数index
    assert false
} catch (e) {
    assert e instanceof ArrayIndexOutOfBoundsException
}

List作为布尔表达式

可以将列表总括为boolean

// 空list = false
assert ![]

//所有有内容的list都 = true
assert [1] && ['a'] && [0] && [0.0] && [false] && [null]

List迭代

迭代列表的成分平常是通过调用eacheachWithIndex情势,它们对列表的每种项进行代码:

[1, 2, 3].each {
    println "Item: $it"//it是对应于当前元素的隐式参数
}
['a', 'b', 'c'].eachWithIndex { it, i -> //it是当前元素, i是索引位置
    println "$i: $it"
}

除此之外迭代之外,通过将各样成分转换为别的因一直创制新的List常常是很有用的。
这几个操作,平时号称映射,在Groovy中经过collect艺术成功:

assert [1, 2, 3].collect { it * 2 } == [2, 4, 6]

//简洁语法
assert [1, 2, 3]*.multiply(2) == [1, 2, 3].collect { it.multiply(2) }

def list = [0]
//可以给“collect”传入list参数,收集元素的列表
assert [1, 2, 3].collect(list) { it * 2 } == [0, 2, 4, 6]
assert list == [0, 2, 4, 6]

list操作

过滤和查找

Groovy开发工具包涵盖众多集结的法子,通过这么些主意进步标准集合的成效,其中部分之类所示:

assert [1, 2, 3].find { it > 1 } == 2           // 找出第一个符合条件的元素
assert [1, 2, 3].findAll { it > 1 } == [2, 3]   //找出所有符合条件的元素
assert ['a', 'b', 'c', 'd', 'e'].findIndexOf {      // 找出符合条件的第一个元素的index
    it in ['c', 'e', 'g']
} == 2

assert ['a', 'b', 'c', 'd', 'c'].indexOf('c') == 2  // 返回index
assert ['a', 'b', 'c', 'd', 'c'].indexOf('z') == -1 // index返回-1意味着没有找到结果
assert ['a', 'b', 'c', 'd', 'c'].lastIndexOf('c') == 4

assert [1, 2, 3].every { it < 5 }               // 如果每一个元素都符合条件则返回true
assert ![1, 2, 3].every { it < 3 }
assert [1, 2, 3].any { it > 2 }                 // 如果有一个元素符合条件就返回true
assert ![1, 2, 3].any { it > 3 }

assert [1, 2, 3, 4, 5, 6].sum() == 21                // 所有元素求和
assert ['a', 'b', 'c', 'd', 'e'].sum {
    it == 'a' ? 1 : it == 'b' ? 2 : it == 'c' ? 3 : it == 'd' ? 4 : it == 'e' ? 5 : 0
    // 求和的时候可以自定义元素的值
} == 15
assert ['a', 'b', 'c', 'd', 'e'].sum { ((char) it) - ((char) 'a') } == 10
assert ['a', 'b', 'c', 'd', 'e'].sum() == 'abcde'
assert [['a', 'b'], ['c', 'd']].sum() == ['a', 'b', 'c', 'd']

// 可以提供初始值
assert [].sum(1000) == 1000
assert [1, 2, 3].sum(1000) == 1006

assert [1, 2, 3].join('-') == '1-2-3'           // 每个元素之间添加字符串
assert [1, 2, 3].inject('counting: ') { str, item -> 
    str + item                     // 减少操作
} == 'counting: 123'
assert [1, 2, 3].inject(0) { count, item ->
    count + item
} == 6

此间是用于在聚集中摸索最大和最小值的惯用Groovy代码:

def list = [9, 4, 2, 10, 5]
assert list.max() == 10
assert list.min() == 2

// 单字符的list也可以查找最大值和最小值
assert ['x', 'y', 'a', 'z'].min() == 'a'

// 我们可以用Closure闭包来描述元素的大小
def list2 = ['abc', 'z', 'xyzuvw', 'Hello', '321']
assert list2.max { it.size() } == 'xyzuvw'
assert list2.min { it.size() } == 'z'

除此之外闭包之外,您还足以应用Comparator来定义相比标准:

Comparator mc = { a, b -> a == b ? 0 : (a < b ? -1 : 1) }

def list = [7, 4, 9, -6, -1, 11, 2, 3, -9, 5, -13]
assert list.max(mc) == 11
assert list.min(mc) == -13

Comparator mc2 = { a, b -> a == b ? 0 : (Math.abs(a) < Math.abs(b)) ? -1 : 1 }


assert list.max(mc2) == -13
assert list.min(mc2) == -1

assert list.max { a, b -> a.equals(b) ? 0 : Math.abs(a) < Math.abs(b) ? -1 : 1 } == -13
assert list.min { a, b -> a.equals(b) ? 0 : Math.abs(a) < Math.abs(b) ? -1 : 1 } == -1
丰盛或删除成分

咱俩得以采纳[]分配一个新的空List,使用<<为List添加项目:

def list = []
assert list.empty

list << 5
assert list.size() == 1

list << 7 << 'i' << 11
assert list == [5, 7, 'i', 11]

list << ['m', 'o']
assert list == [5, 7, 'i', 11, ['m', 'o']]

//在<<表达式最前端的list是目标list
assert ([1, 2] << 3 << [4, 5] << 6) == [1, 2, 3, [4, 5], 6]

//使用leftShift方法等价于使用 <<
assert ([1, 2, 3] << 4) == ([1, 2, 3].leftShift(4))

我们得以经过三种主意丰裕到List中:

assert [1, 2] + 3 + [4, 5] + 6 == [1, 2, 3, 4, 5, 6]
// 等价于调用plus方法
assert [1, 2].plus(3).plus([4, 5]).plus(6) == [1, 2, 3, 4, 5, 6]

def a = [1, 2, 3]
a += 4      //创建了一个新的List
a += [5, 6]
assert a == [1, 2, 3, 4, 5, 6]

assert [1, *[222, 333], 456] == [1, 222, 333, 456]
assert [*[1, 2, 3]] == [1, 2, 3]
assert [1, [2, 3, [4, 5], 6], 7, [8, 9]].flatten() == [1, 2, 3, 4, 5, 6, 7, 8, 9]

def list = [1, 2]
list.add(3)
list.addAll([5, 4])
assert list == [1, 2, 3, 5, 4]

list = [1, 2]
list.add(1, 3) //在索引1前面插入元素3
assert list == [1, 3, 2]

list.addAll(2, [5, 4]) //在索引2前面插入元素[5,4]
assert list == [1, 3, 5, 4, 2]

list = ['a', 'b', 'z', 'e', 'u', 'v', 'g']
list[8] = 'x' // []运算符根据需要使列表增长
// 如果需要插入null
assert list == ['a', 'b', 'z', 'e', 'u', 'v', 'g', null, 'x']

而是,紧要的是List上的+运算符不会变动List本人。
<<相比,+运算符会创造五个新的列表,这一般不是您想要的,并可能造成品质难点。

Groovy开发包还含有部分措施,使您可以通过成分值轻松地从列表中删除成分:

assert ['a','b','c','b','b'] - 'c' == ['a','b','b','b']
assert ['a','b','c','b','b'] - 'b' == ['a','c']
assert ['a','b','c','b','b'] - ['b','c'] == ['a']

def list = [1,2,3,4,3,2,1]
list -= 3           //从原始list创建一个新的list,并删除元素3
assert list == [1,2,4,2,1]
assert ( list -= [2,4] ) == [1,1]

也足以通过引用其索引来删除成分,在那种情状下,列表会改变:

def list = [1,2,3,4,5,6,2,2,1]
assert list.remove(2) == 3          //删除第三个元素并返回第三个元素的值
assert list == [1,2,4,5,6,2,2,1]

万一你只想删除列表中兼有相同值的率先个成分,而不是去除全数因素,则调用remove方法:

def list= ['a','b','c','b','b']
assert list.remove('c')             // 删除元素'c'如果删除成功返回true
assert list.remove('b')             // 删除第一个找到的元素'b',如果删除成功返回true
assert ! list.remove('z')           // 返回false,因为没有任何元素删除
assert list == ['a','b','b']

去除列表中的全数因素得以透过调用clear主意来形成:

def list= ['a',2,'c',4]
list.clear()
assert list == []
设置操作

Groovy开发工具包还包涵一些办法,使得它不难推理:

assert 'a' in ['a','b','c']             // 如果元素'a'在list中返回true
assert ['a','b','c'].contains('a')      // 等价于java中的`contains`方法
assert [1,3,4].containsAll([1,4])       // `containsAll` 将检测每一个待查元素,如果都包含在list中,返回true

assert [1,2,3,3,3,3,4,5].count(3) == 4  // 返回元素3在列表中包含的数量
assert [1,2,3,3,3,3,4,5].count {
    it%2==0                             // 返回符合断言的元素在列表中包含的数量
} == 2

assert [1,2,4,6,8,10,12].intersect([1,3,6,9,12]) == [1,6,12]//返回两个列表的交集

assert [1,2,3].disjoint( [4,6,9] )//两个列表是互斥的,返回true
assert ![1,2,3].disjoint( [2,4,6] )
排序

运用List平时会赶上排序。
Groovy提供了种种选项来排序List,从使用闭包到comparators,如下例所示:

assert [6, 3, 9, 2, 7, 1, 5].sort() == [1, 2, 3, 5, 6, 7, 9]

def list = ['abc', 'z', 'xyzuvw', 'Hello', '321']
assert list.sort {
    it.size()
} == ['z', 'abc', '321', 'Hello', 'xyzuvw']

def list2 = [7, 4, -6, -1, 11, 2, 3, -9, 5, -13]
assert list2.sort { a, b -> a == b ? 0 : Math.abs(a) < Math.abs(b) ? -1 : 1 } ==
        [-1, 2, 3, 4, 5, -6, 7, -9, 11, -13]

Comparator mc = { a, b -> a == b ? 0 : Math.abs(a) < Math.abs(b) ? -1 : 1 }

// 仅限于JDK 8+
// list2.sort(mc)
// assert list2 == [-1, 2, 3, 4, 5, -6, 7, -9, 11, -13]

def list3 = [6, -3, 9, 2, -7, 1, 5]

Collections.sort(list3)
assert list3 == [-7, -3, 1, 2, 5, 6, 9]

Collections.sort(list3, mc)
assert list3 == [1, 2, -3, 5, 6, -7, 9]
复制元素

Groovy开发工具包还使用了操作符重载,以提供允许复制列表元素的主意:

assert [1, 2, 3] * 3 == [1, 2, 3, 1, 2, 3, 1, 2, 3]
assert [1, 2, 3].multiply(2) == [1, 2, 3, 1, 2, 3]
assert Collections.nCopies(3, 'b') == ['b', 'b', 'b']

// 来自JDK的nCopies具有与列表的乘法不同的语义
assert Collections.nCopies(2, [1, 2]) == [[1, 2], [1, 2]] //而不是[1,2,1,2]

Maps

Map 字面值

在Groovy中,可以使用map语法创立map(也称为关联数组):[:]

def map = [name: 'Gromit', likes: 'cheese', id: 1234]
assert map.get('name') == 'Gromit'
assert map.get('id') == 1234
assert map['name'] == 'Gromit'
assert map['id'] == 1234
assert map instanceof java.util.Map

def emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.put("foo", 5)
assert emptyMap.size() == 1
assert emptyMap.get("foo") == 5

暗中认同意况下,map的key是字符串:[a:1]等价于['a':1]
固然您定义贰个名为a的变量,并且您希望a的值为你的map的key,那恐怕会令人猜忌。
假若是那种情景,则必须经过添加括号来转义键,如以下示例所示:

def a = 'Bob'
def ages = [a: 43]
assert ages['Bob'] == null // 找不到`Bob`
assert ages['a'] == 43     // 因为 `a` 是字面值(文本)!

ages = [(a): 43]            // 将`a`用()括起来
assert ages['Bob'] == 43   // 这时就能找到'Bob'的值了

除去map 字面值外, 也得以透过clone方法拿到二个map的副本:

def map = [
        simple : 123,
        complex: [a: 1, b: 2]
]
def map2 = map.clone()
assert map2.get('simple') == map.get('simple')
assert map2.get('complex') == map.get('complex')
map2.get('complex').put('c', 3)
assert map.get('complex').get('c') == 3

如前方的以身作则所示,生成的map是原始map的浅拷贝

Map属性符号

Maps也像bean一样,所以您可以采取性能符号在Map中get/set项,只要键是卓有功能的Groovy标识符的字符串即可:

def map = [name: 'Gromit', likes: 'cheese', id: 1234]
assert map.name == 'Gromit'     // 同map.get('Gromit')
assert map.id == 1234

def emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.foo = 5
assert emptyMap.size() == 1
assert emptyMap.foo == 5

留意:遵照设计,map.foo会直接在map中查找这些key。那象征foo.class将在不分包class键的map上回来null。如若你是想回到foo的项目,那么您必须采取foo.getClass()方法:

def map = [name: 'Gromit', likes: 'cheese', id: 1234]
assert map.class == null
assert map.get('class') == null
assert map.getClass() == LinkedHashMap // 这很可能是你想要的结果

map = [1      : 'a',
       (true) : 'p',
       (false): 'q',
       (null) : 'x',
       'null' : 'z']
assert map.containsKey(1) // 数字1不是一个标识符,所以得这样调用
assert map.true == null
assert map.false == null
assert map.get(true) == 'p'
assert map.get(false) == 'q'
assert map.null == 'z'
assert map.get(null) == 'x'

Map迭代

照例,在Groovy开发工具包中,Map上的惯用迭代使用eacheachWithIndex主意。
值得注意的是,使用Map字面值符号创立的Map是有序的,相当于说,借使对Map条目进行迭代,将确保条目将依照它们在Map中添加的依次再次来到。

def map = [
        Bob  : 42,
        Alice: 54,
        Max  : 33
]

// `entry` is a map entry
map.each { entry ->
    println "Name: $entry.key Age: $entry.value"
}

// `entry` is a map entry, `i` the index in the map
map.eachWithIndex { entry, i ->
    println "$i - Name: $entry.key Age: $entry.value"
}

// Alternatively you can use key and value directly
map.each { key, value ->
    println "Name: $key Age: $value"
}

// Key, value and i as the index in the map
map.eachWithIndex { key, value, i ->
    println "$i - Name: $key Age: $value"
}

Map操作

添加或删除元素

向Map中添比索素可以动用put主意,下标运算符或利用putAll

def defaults = [1: 'a', 2: 'b', 3: 'c', 4: 'd']
def overrides = [2: 'z', 5: 'x', 13: 'x']

def result = new LinkedHashMap(defaults)
result.put(15, 't')
result[17] = 'u'
result.putAll(overrides)
assert result == [1: 'a', 2: 'z', 3: 'c', 4: 'd', 5: 'x', 13: 'x', 15: 't', 17: 'u']

去除Map的兼具因素得以通过调用clear方法来成功:

def m = [1:'a', 2:'b']
assert m.get(1) == 'a'
m.clear()
assert m == [:]

拔取Map字面值语法生成的Map使用object的equalshashcode办法。
那意味你不应有使用哈希码随时间变化的object,否则你将无法赢得相关的值。

还值得注意的是,您不应有运用GString作为Map的键,因为GString的哈希码与同样String的哈希码不一致:

def key = 'some key'
def map = [:]
def gstringKey = "${key.toUpperCase()}"
map.put(gstringKey,'value')
assert map.get('SOME KEY') == null
Keys, values and entries

咱俩得以检查视图中的keys, values, and entries:

def map = [1:'a', 2:'b', 3:'c']

def entries = map.entrySet()
entries.each { entry ->
  assert entry.key in [1,2,3]
  assert entry.value in ['a','b','c']
}

def keys = map.keySet()
assert keys == [1,2,3] as Set

鉴于操作的打响直接取决高满堂在操作的Map的类型,由此视图(不管是map的entry,key照旧value)重临的变化值是那二个不鼓励的。
尤其地,Groovy依赖于来自JDK的联谊,寻常不可以担保集合可以通过keySetentrySetvalues有惊无险地操作。

过滤和搜索

Groovy开发包包含与List中类似的过滤,搜索和采访形式:

def people = [
    1: [name:'Bob', age: 32, gender: 'M'],
    2: [name:'Johnny', age: 36, gender: 'M'],
    3: [name:'Claire', age: 21, gender: 'F'],
    4: [name:'Amy', age: 54, gender:'F']
]

def bob = people.find { it.value.name == 'Bob' } // 查找单个entry
def females = people.findAll { it.value.gender == 'F' }

//两个都是返回entries,但是您可以使用collect来检索年龄例如
def ageOfBob = bob.value.age
def agesOfFemales = females.collect {
    it.value.age
}

assert ageOfBob == 32
assert agesOfFemales == [21,54]

// 但您也可以使用键/对值作为闭包的参数but you could also use a key/pair value as the parameters of the closures
def agesOfMales = people.findAll { id, person ->
    person.gender == 'M'
}.collect { id, person ->
    person.age
}
assert agesOfMales == [32, 36]

// `every` 如果所有entries都匹配规则,则返回true
assert people.every { id, person ->
    person.age > 18
}

// `any` 如果任何一个entry匹配规则,则返回true
assert people.any { id, person ->
    person.age == 54
}
分组

咱俩得以采用一些标司令员List分组到Map中:

assert ['a', 7, 'b', [2, 3]].groupBy {
    it.class
} == [(String)   : ['a', 'b'],
      (Integer)  : [7],
      (ArrayList): [[2, 3]]
]

assert [
        [name: 'Clark', city: 'London'], [name: 'Sharma', city: 'London'],
        [name: 'Maradona', city: 'LA'], [name: 'Zhang', city: 'HK'],
        [name: 'Ali', city: 'HK'], [name: 'Liu', city: 'HK'],
].groupBy { it.city } == [
        London: [[name: 'Clark', city: 'London'],
                 [name: 'Sharma', city: 'London']],
        LA    : [[name: 'Maradona', city: 'LA']],
        HK    : [[name: 'Zhang', city: 'HK'],
                 [name: 'Ali', city: 'HK'],
                 [name: 'Liu', city: 'HK']],
]

Ranges

Ranges允许你创造顺序值List。
这个足以看作List,因为Range扩展了java.util.List

使用..标记定义的界定是包涵性的(即List包蕴from和to值)。

使用.. <标记定义的限定是半开的,它们包括率先个值,但不是终极五个值。

// 全包含的range
def range = 5..8
assert range.size() == 4
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert range.contains(8)

// 半开的range
range = 5..<8
assert range.size() == 3
assert range.get(2) == 7
assert range[2] == 7
assert range instanceof java.util.List
assert range.contains(5)
assert !range.contains(8)

//获取range的端点而不使用索引
range = 1..10
assert range.from == 1
assert range.to == 10

请留心,int类型的Range已毕了高效用,创造了贰个包涵from和to值的轻量级Java对象。

Ranges可以用于落实java.lang.Comparable以拓展比较的任何Java对象,并且还有方法next()previous()回来range中的下2个/上1个品类。
例如,您可以成立一多元String成分:

// 全包括range
def range = 'a'..'d'
assert range.size() == 4
assert range.get(2) == 'c'
assert range[2] == 'c'
assert range instanceof java.util.List
assert range.contains('a')
assert range.contains('d')
assert !range.contains('e')

你可以采取经典的for循环在2个range上进行迭代:

for (i in 1..10) {
    println "Hello ${i}"
}

但是如故,您可以因而采纳each措施迭代Range,在越发Groovy惯用的品格中贯彻均等的机能:

(1..10).each { i ->
    println "Hello ${i}"
}

Range也得以用在switch语句中:

switch (years) {
    case 1..10: interestRate = 0.076; break;
    case 11..25: interestRate = 0.052; break;
    default: interestRate = 0.037;
}

汇聚的语法增强

GPath支持

出于对List和Map的品质符号帮忙,Groovy提供了语法糖,使得拍卖嵌套集合变得万分不难,如下例所示:

def listOfMaps = [['a': 11, 'b': 12], ['a': 21, 'b': 22]]
assert listOfMaps.a == [11, 21] //GPath 标记
assert listOfMaps*.a == [11, 21] //扩展点符号

listOfMaps = [['a': 11, 'b': 12], ['a': 21, 'b': 22], null]
assert listOfMaps*.a == [11, 21, null] // 适用于空值
assert listOfMaps*.a == listOfMaps.collect { it?.a } //等价符号
// 但这只会收集非空值
assert listOfMaps.a == [11,21]

增添运算符

壮小运算符可以用于将汇聚“内联”到另三个汇聚中。
它是语法糖,寻常幸免调用putAll并有助于一行的落到实处:

assert [ 'z': 900,
         *: ['a': 100, 'b': 200], 'a': 300] == ['a': 300, 'b': 200, 'z': 900]
//在map定义中的扩展map符号
assert [*: [3: 3, *: [5: 5]], 7: 7] == [3: 3, 5: 5, 7: 7]

def f = { [1: 'u', 2: 'v', 3: 'w'] }
assert [*: f(), 10: 'zz'] == [1: 'u', 10: 'zz', 2: 'v', 3: 'w']
//函数参数中的扩展map符号
f = { map -> map.c }
assert f(*: ['a': 10, 'b': 20, 'c': 30], 'e': 50) == 30

f = { m, i, j, k -> [m, i, j, k] }
//使用具有混合未命名和命名参数的展开map符号
assert f('e': 100, *[4, 5], *: ['a': 10, 'b': 20, 'c': 30], 6) ==
        [["e": 100, "b": 20, "c": 30, "a": 10], 4, 5, 6]

星号“*”运算符

“星点”运算符是贰个神速运算符,允许你对聚集的持有因素调用方法或性质:

assert [1, 3, 5] == ['a', 'few', 'words']*.size()

class Person {
    String name
    int age
}
def persons = [new Person(name:'Hugo', age:17), new Person(name:'Sandra',age:19)]
assert [17, 19] == persons*.age

利用下标运算符切片

您可以行使下标表明式将其索引到list,数组和map中。
有趣的是,字符串在那种景观下被视为非常类其余聚合:

def text = 'nice cheese gromit!'
def x = text[2]

assert x == 'c'
assert x.class == String

def sub = text[5..10]
assert sub == 'cheese'

def list = [10, 11, 12, 13]
def answer = list[2,3]
assert answer == [12,13]

请留心,您可以行使Range提取集合的一局地:

list = 100..200
sub = list[1, 3, 20..25, 33]
assert sub == [101, 103, 120, 121, 122, 123, 124, 125, 133]

下标运算符可用于更新现有集合(对于不可变的聚合类型):

list = ['a','x','x','d']
list[1..2] = ['b','c']
assert list == ['a','b','c','d']

值得注意的是,允许选拔负索引,从集合的末段更易于提取:
您可以采取负指数从List,array,String等末梢计数。

text = "nice cheese gromit!"
x = text[-1]
assert x == "!"

def name = text[-7..-2]
assert name == "gromit"

最后,如果采纳向后Range(开始索引大于为止索引),则答案将扭曲。

text = "nice cheese gromit!"
name = text[3..1]
assert name == "eci"

拉长的集结方法

除外List,Map或Ranges,Groovy还提供了重重附加的过滤,收集,分组,计数等格局,这个艺术可以一向在汇聚上采用,或然更易于迭代。

尤其是,大家特邀您读书Groovy开发包API文档,具体来说:

  • 添加到Iterable的不二法门可以从这里找到
  • 添加到Iterator的方法可以从这里找到
  • 添加到Collection的法子可以从这里找到
  • 添加到List的点子能够从这里找到
  • 添加到Map的法门可以从这里找到

ps:
literals这些单词应该翻译成什么更合适些呢,有心上人通晓的话可以留言List
literals 小编翻译成了 List字面值 鲜明是颠三倒四的

相关文章