Groovy集合(map)

聲明map

Map的規範和上一篇博客提到的list類似,helist一樣,Map保證可以通過下標來獲取或者設置值,不同的是map可以使用任何類型作爲下標操作符的參數,而list僅僅支持整數,list知道list中元素的順序,而map一般不知道,特殊的map如java.util.TreeMap也可以知道他們的key的順序。

理論上 ,任何類型都可以作爲map的鍵(key)或者值(value),當使用特殊類型作爲key的時候,需要遵循java.util.Map在javaDoc中的規定。

通過[:]來聲明一個空的map,map缺省的類型是java.util.HashMap,也可以通過調用構造方法進行顯示聲明,這樣map仍然可以使用下標操作符進行操作。

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

assert map instanceof HashMap
assert map.size() == 3
assert map['a'] == 1

emptyMap = [:]
assert map.size() == 0

explicitMap = new TreeMap()
explicitMap.putAll(map)
assert explicitMap['a'] == 1

一般情況下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 ['(x)'] == ['x':1]

使用map操作符

Groovy中有三種從map中獲取對象的方法:

  1. 使用下表操作符,因爲map實現了getAt方法;
  2. 使用點語法像使用屬性那樣來獲取對象;
  3. 使用get()方法,可以傳遞一個缺省值,在map中沒有相應的key時,允許返回缺省值,如果沒有缺省值放回null,如果get(key,default)被調用時,key沒有找到,缺省值返回,那麼key:defualt對將被增加到map中。
def map == [a:1,b:2,c:3]

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

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

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

map['d']        = 1         
assert map.d    == 1
map.d       = 2
assert map.d    == 2

將值分配給map時可以使用下標操作符或者點語法,在使用點語法時,如果key包含了特殊字符,需要使用字符串符號括起來。

map = ["a.b" : 1]
assert map.'a.b'    == 1    

如果僅僅寫成map.a.b,這裏是不會正常工作的,這其實等價於map.getA().getB().

map方法

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

assert map == other 

assert map.isEmpty() == false   //是否爲空
assert map.size() == 3
assert map.containKey('a')  //判斷map中是否包含給定的key
assert map.containValue(1)  //判斷map中是否包含給定的value
//keySet()返回一個key的set集合,不包含重複的key,沒有固定的順序
assert map.keySet() == toSet(['a','b','c'])
assert toSet(map.values()) == toSet([1,2,3])
assert map.entrySet() instanceof Collection

assert map.any{entry -> entry.value > 2}    //與list中同名方法類似,
assert map.every{entry -> entry.key < 'd'}

def toSet(list){
    new java.util.HashSet(list)
}

遍歷map


//each()  
//each()接受兩種形式的閉包:傳遞一個參數,那麼這個參數代表map的一個entry;傳遞兩個參數,那麼就是key和value
def map = [a:1,b:2,c:3]

def store = ''
map.each{entry -> store += entry.key + entry.value}
assert store == "a1b2c3"

def store = ''
map.each{key,value -> store += key  store += value}
assert store == "a1b2c3"

修改map

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

def map = [a:1,b:2,c:3]
map.remove('a')
assert map.size() == 2

def map = [a:1,b:2,c:3]
assert [a:1,b:2] == map.subMap(['a','b']) 
assert [a:1,b:2] == map.findAll{entry -> entry.value < 3}

neWMap = map.find{entry -> entry.value < 3} //返回符合條件一個entry

//collect() 返回閉包結果組成的list(是否返回可選)
assert [2,4,6] == map.collect{entry -> entry.value*= 2}
//collect()可以接受一個list
assert [1,2,2,4,6] == map.collect([1,2]){entry -> entry.value*= 2}

map實戰

統計文章中單詞出現的頻率


def text = 
"""
When I say I believe all children can learn, people sometimes misunderstand.
Because I have been working with poor, minority children in Harlem for the last 25 years, 
some people think I am talking about good kids in bad environments — that if you give a bright kid from a poor family a good educational support system,
 he or she can succeed. That's absolutely true, but that's not what I mean

"""

def works = text.tokenize()
def wordFrequency = [:]
words.each{work -> 
    wordFrequency[work] = wordFrequency.get(work,0) + 1 
}

def workList = wordFrequency.keySet().toList()
workList.sort{wordFrequency[it]}

def statistic = "\n"
workList[-1..-6].each{work -> 
    statistic += work.padLeft(12) + ":"
    statistic += wordFrequency[work] + "\n"
}

assert statistic == 
"""
            I:5
            a:3
         good:2
           in:2
       people:2
          can:2
"""
發佈了39 篇原創文章 · 獲贊 66 · 訪問量 19萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章