容器
原创大约 4 分钟
List
Groovy中的List
既是java.util.List
接口的实例,同时也默认
是java.util.ArrayList
的实例(可以更改),但它又具有Python或Scala中元组Tuple
的特性:可以存放不同类型的数据。
List
的下标也是从0
开始计算的。
> def list1 = [1, 2, 3]
> println(list1 instanceof List)
> println(list1 instanceof ArrayList)
> println(list1.size() == 3)
> println(list1[0] == 1)
> def list2 = [1, 3.14, "groovy", true]
> println(list2 instanceof List)
> println(list2.size() == 4)
> println(list2[3] == true)
true
true
true
true
true
true
true
可以通过显式地指定类型或as
操作符,定义一个java.util.LinkedList
。
> def linkedList = [1, 2, 3] as LinkedList
> println(linkedList instanceof LinkedList)
> LinkedList otherLinked = [4, 5, 6]
> println(otherLinked instanceof LinkedList)
true
true
对List
的操作也都继承了java.util.List
中的方法,可以像操作java.util.List
那样操作它。java.util.List
中的有些操作方法又像是Python或Go中的切片
。
> def list = ['a', 3.14, 'c', 0]
// 读取元素
> println(list[0] == 'a')
> println(list[1] == 3.14)
> println(list[-1] == 0)
> println(list[-2] == 'c')
true
true
true
true
// 修改元素
> list[2] = 'C'
> println(list)
[a, 3.14, C, 0]
// 默认在尾部添加元素
> list.add(1)
> println(list)
[a, 3.14, C, 0, 1]
// 向指定位置插入元素
> list.add(0, "0")
> println(list)
[0, a, 3.14, C, 0, 1]
// 向尾部追加元素
> list << 'e'
> println(list)
[0, a, 3.14, C, 0, 1, e]
// 删除元素默认用的是下标,如果元素第一个数值是0,就容易弄混
> list.remove(0)
// 如果用的是非整数数字,那么就是删除指定的元素
> list.remove(3.14)
> println(list)
[a, C, 0, 1, e]
// 删除一个不存在的元素也不会报错
> list.remove("2")
> println(list)
[a, C, 0, 1, e]
// 挑出指定位置的元素
> println(list[1, 3])
[C, 1]
// 这种相等性判断,不仅判断数值是否相同,同时也会检查类型是否匹配。如果数值类型不同,也会返回false
> println(list[1, 3] == ['C', '1']) // false
false
// 因为List中的1是整型,所以返回true。因此建议List最好使用同一种数据类型,否则在取出数据时不小心就会搞错
> println(list[1, 3] == ['C', 1]) // true
true
// 切片操作:挑出指定范围的元素
> println(list[2..4])
[0, 1, e]
> println(list[2..4] == [0, 1, 'e'])
true
多维List
的定义和使用也很简单。
> def multi = [[0, 1], [2, 3]]
> println(multi[1][0] == 2)
true
Array
Groovy用和java.util.List
同样的形式和符号来表示Array
(数组
)。
> String[] arrStr1 = ['Ananas', 'Banana', 'Kiwi']
> println(arrStr1 instanceof String[])
true
// 除非明确指明它是一个String[],否则它就是一个List
> def arrStr2 = ['Ananas', 'Banana', 'Kiwi']
> println(arrStr2 instanceof List)
true
// 使用as来明确指明类型
> def numArr = [1, 2, 3] as int[]
> println(numArr instanceof int[])
true
> println(numArr.size() == 3)
true
// 也可以使用Arrays来定义数组,但如果不明确指定,那它就是List
> def arrStr3 = Arrays.asList(1, 'hello', 3.14, 'groovy', true)
> println(arrStr3)
[1, hello, 3.14, groovy, true]
> println(arrStr3 instanceof List)
true
> String[] arrStr4 = Arrays.asList(1, 'hello', 3.14, 'groovy', true)
> println(arrStr4)
[1, hello, 3.14, groovy, true]
> println(arrStr4 instanceof String[])
true
可以在定义时候就指定数组长度。
> def multiDim1 = new Integer[3][3]
> println(multiDim1.length == 3)
true
> Integer[][] multiDim2
> multiDim2 = [[1, 2], [3, 4]]
> println(multiDim2 instanceof Integer[][])
true
操作Array
的方法和操作List
一样,但不同的是,只要是指定了数组类型,那么数组中的元素都是指定的类型,而不像List
那样有很多不同的类型。
> String[] arrs = [1, 'hello', 3.14, 'groovy', true]
> println(arrs)
[1, hello, 3.14, groovy, true]
// String[]数组中都是String类型
> println(arrs[2] == 3.14) // false
false
> println(arrs[2] == '3.14') // true
true
> arrs[2] = 1.23
> println(arrs)
[1, hello, 1.23, groovy, true]
// 虽然修改元素时传的是浮点数,但保存时自动转换成了字符串
> println(arrs[2] == '1.23')
true
所有Java用于初始化数组的操作,也都可以用于Groovy。
> def intArr = new int[] {1, 3, 5, 7, 9}
// Array既可以用length属性表示长度,也可以用size()方法来表示
> println((intArr.length == 5 || intArr.size() == 5) && intArr.sum() == 25)
true
> println(intArr.class.name == '[I')
true
> def pets = new String[] {'cat', 'dog'}
> println((pets.length == 2 || pets.size() == 2) && pets.sum() == 'catdog')
true
> println(pets.class.name == '[Ljava.lang.String;')
true
> String[] books = [ 'Groovy in Action', 'Making Java Groovy' ]
> println(books.every{ it.contains('Groovy') })
true
Map
Groovy中的Map
和List
类似,既是java.util.Map
的实例,同时也是java.util.LinkedHashMap
的实例,而且Groovy对错误也比较宽容,不像Java那样动不动就抛NullPointException
。
> def user = [name: 'lixingyun', age: 20, city: 'wuhan']
// Map的完整写法是java.util.Map
> println(user instanceof Map)
true
// 和Map类似
> println(user instanceof LinkedHashMap)
true
> println(user['name'] == 'lixingyun')
true
> println(user.age == 20)
true
// 添加或访问键值对的两种方式
> user['province'] = 'hubei'
> user.gender = 'male'
> println(user.province == 'hubei')
true
> println(user['gender'] == 'male')
true
// 访问不存在的键值时会返回null,而不是NullPointException
> println(user.password == null)
true
除了字符串可以用作key
,数字也可以,但不推荐。
> def numbers = [1: 'one', 2: 'two']
> println(numbers[1] == 'one')
true
// 这种方式会抛出异常groovy.lang.MissingMethodException
> println(numbers.1 == 'two')
groovy.lang.MissingMethodException: No signature of method: ......
如果用变量来代替key
,又会发生什么情况?
> def key = 'name'
> def person = [key: 'groovy']
> // 用变量作为key,会发现变量值没有用,但变量名却成了key
> println(!person.containsKey('name'))
true
> println(person.containsKey('key'))
true
> // 只有这样用变量代替key才有效
> person = [(key): 'groovy']
> println(person.containsKey('name'))
true
> println(!person.containsKey('key'))
true
感谢支持
更多内容,请移步《超级个体》。