Groovy预览--简单的映射(maps)

1简单的映射(maps)

一个map是用来给一个键(key)分配值(value)的强类型,map可以通过key存储和找回valuea.
不像java,groovy在语言级别支持map,允许使用特定的操作符来操作map,maps的操作语法像键-值对数组,通过冒号分割key-valuea.

def http=[:]  //声明一个map
println http.size()
http['syn']='Hello Synvata'//向map添加K-V
println http['syn']      
一般情况下key的类型都是字符串,在声明map的时候可以忽略字符串标记(单引号或者双引号): 
  assert ['a':1] == [a:1]
如果key没有包括特殊的字符(需要符合有效标识符规则)并且不是groovy的关键字,那么允许通过这么便利的方式进行声明。 这种方式也有不便的地方,例如,本地变量的内容被用作key。

假设有一个本地变量x,它的内容为‟a‟,由于[x:1]等价于['x':1],那么该怎样保证它等于['a',1]呢?通过把符号放在圆括号中,强制让groovy将符号看做为一个表达式:
  def x = 'a'
  assert ['x':1] == [x:1]  
  assert ['a':1] == [(x):1]
需要进行这样的操作比较罕见,但是当需要从本地符号(本地变量、字段、属性)得到一个key的时候,忘记插入圆括号可能导致错误。

2使用map操作符

使用map最简单的操作是使用key存储对象到map中和通过key从map中获取对象。
  1.从map中获取对象的一种可选方式是使用下标操作符,这基于map实现了getAt方法;
  2.另外一种可选方式是使用点语法像使用属性那样来获取对象;
  3.第三种选择是使用get方法,这个方法允许传递一个缺省值,在map没有相应的key的时候允许返回这个值。如果没有指定缺省值,null将为缺省,
   如果get(key,default)被调用时,key没有找到并且缺省值被返回,那么key:default对将被增加到map中。
   将值分配给map时可以使用下标操作符或者点语法,在使用点语法的时候,如果key包含了特殊字符,需要使用字符串符号(单引号或者双引号)围起来,如下所示:
def myMap=[a:1, b:2, c:3]

assert myMap['a'] == 1
assert myMap.a == 1
assert myMap.get('a') == 1
assert myMap.get('a',0) == 1

assert myMap['d'] == null
assert myMap.d == null
assert myMap.get('d') == null

assert myMap.get('d',0) == 0
assert myMap.d == 0

assert myMap.get('e',1) == 1
assert myMap.e == 1


myMap = ['a.b':1] 
assert myMap.'a.b' == 1 
如果仅仅写成myMap.a.b,在这里是不会正常工作的,这其实等价于myMap.getA().getB()。
keySet方法返回一个key的set集合,set是一个像list,但不包括重复的元素,并且集合中的元素没有固定的顺序,更详细的信息请参考java.util.Set的JavaDoc,为了比较keySet是否与给定的list中的key,在这里将这个list转换为一个set,这是通过方法toSet来实现的。
values方法返回map的值(value)的列表,由于map没有办法知道key的顺序,因此不能了解value列表的顺序,为了与预知的list中的值进行比较,在这里将两个list都转换为set。
def myMap=[a:1, b:2, c:2]
def toSet(list){
    new java.util.HashSet(list)
}
println toSet(myMap.values())  //[1, 2]

println myMap.keySet()         //[a, b, c]

Map的each方法接受两种形式的闭包:传递一个参数给闭包,那么这个参数就是map的一个entry;传递两个参数给闭包,那么参数就是key和value,一般来说,后者在实际工作中更方便。

def myMap=[a:1, b:2, c:2]
def store=''
myMap.each{entry ->
    store += entry.key
    store += entry.value
}
println store   //a1b2c2

store=''
myMap.each{key,value ->
    store += key
    store += value
}
println store   //a1b2c2

store=''
for(value in myMap.values()){
    store += value
}
println store  //122

最后,可以通过几种不同的途径来进行map内容的修改,可以通过原始的JDK的方法来移除元素,GDK引入的新的途径如下:
通过给定一个key的集合来创建一个子map(subMap),这个子map的所有实体的key都来自这个集合;

findAll用来查找满足闭包要求的所有map实体;

find用来查找任意一个满足闭包要求的map实体,这里不像list那样查找的是第一个满足闭包要求的实体,这是因为map是没有顺序的;

collect为map的每一个实体应用闭包,返回每一个闭包应用的结果组成的list(闭包是否返回结果是可选的)

def myMap=[a:1, b:2, c:2]
myMap.clear()
assert myMap.isEmpty()

myMap=[a:1, b:2, c:3]
myMap.remove('a')
println myMap   //[b:2, c:3]


myMap=[a:1, b:2, c:3]
def sub=myMap.subMap(['a','b'])
println sub     //[a:1, b:2]


sub=myMap.findAll{entry -> 
    entry.value<3
}
println sub     //[a:1, b:2]

def found=myMap.find{entry -> entry.value < 3}
println found     // a=1
println found.key // a


def doubled=myMap.collect{entry -> entry.value *= 2 }
println doubled     // [2, 4, 6]

 

 




 

 

 

posted @ 2012-05-30 15:12  Johnny Yan  阅读(8587)  评论(0编辑  收藏  举报