groovy> a = [:]
===> {}
groovy> a.getClass()
===> class java.util.LinkedHashMap
// iteracje po mapie mozna wykonac na kilka sposobow
groovy> a = [a:'aa',b:'bb']
===> {a=aa, b=bb}
groovy> a.each{println it}
a=aa
b=bb
===> {a=aa, b=bb}
groovy> a.each{println it.key}
a
b
===> {a=aa, b=bb}
groovy> a.each{println it.value}
aa
bb
===> {a=aa, b=bb}
groovy> a.each{ key,value -> println key + ' - ' + value }
a - aa
b - bb
===> {a=aa, b=bb}
// ustawianie i odczytywanie elementów jest proste,
groovy> a.a
===> aa
groovy> a.b
===> bb
groovy> a.c
===> null
// ale z powodu takiej konwencji a.class == null, dlatego wcześniej użyłem getClass()
// na mapie można bezpośrednio tworzyć nowy element w analogiczny sposób
groovy> a.c = 'cc'
===> cc
groovy> a
===> {a=aa, b=bb, c=cc}
groovy> a['d'] = 123
===> 123
groovy> a
===> {a=aa, b=bb, c=cc, d=123}
groovy> a.keySet()
===> [a, b, c, d]
groovy> a.values()
===> [aa, bb, cc, 123]
Klucz w mapie domyslnie jest traktowany jako string, chyba ze jest liczbą, wartością logiczną lub null.
groovy> b = [1:1,a:2]
===> {1=1, a=2}
groovy> b[1]
===> 1
groovy> b['a']
===> 2
groovy> b.'1'
===> null
groovy> b[a]
===> null
Jeśli chcemy jako klucz użyć coś innego niż liczbę czy string to możemy użyć notacji tabeli asocjacyjnej mapa[obiekt], albo nawiasów():
groovy> x = [1,2]Jeśli mapa jest parametrem funkcji to większości przypadków można porzucić nawiasy []
===> [1, 2]
groovy> y = [ (x):'abc' ] //dzieki nawiasom w tym przypadku kluczem będzie lista
===> {[1, 2]=abc}
groovy> y.keySet()*.getClass()
===> [class java.util.ArrayList]
groovy> y.each{println it.key[1]}
2
===> {[1, 2]=abc}
groovy> f = {mapa -> mapa.values().each{ println it }}nawet jeśli mapa nie jest jedynym parametrem
===> groovysh_evaluate$_run_closure1@1e46a68
groovy> f([a:1])
1
===> [1]
groovy> f([a:1,b:2])
1
2
===> [1, 2]
groovy> f(a:1,b:2)
1
2
===> [1, 2]
groovy> g = {mapa, foo -> println mapa}
===> groovysh_evaluate$_run_closure1@d480ea
groovy> g(a:1,2)
["a":1]
===> null
groovy> g(a:1,b:2,2)
["a":1, "b":2]
===> null
Języki dynamicznie z domknięciami mają ciekawą cechę, mapa odpowiada w pewnym stopniu obiektowi, np. w ActionScript 2 nie ma osobnej kolekcji "Mapa" - korzysta się z Obiektów i dynamicznie tworzy nowe pola wygląda to tak jak kod w 3 linijce.
groovy> a = [:]
===> {}
groovy> a.pole = 1
===> 1
groovy> a.funkcja = { x -> x * a.pole } // ! trzeba zapisać skąd pochodzi "pole", m.in. tym się różni od normalnego obiektu
===> groovysh_evaluate$_run_closure1@20f237
groovy> a.funkcja(2)
===> 2
groovy> a.pole = 2
===> 2
groovy> a.funkcja(2)
===> 4
groovy>
Teraz, chwila przerwy, by każdy czytelnik mógł się zastanowić jak proste jest tworzenie mocków w Groovy za pomocą takich opcji.
Istnieje jeszcze jedna specjalna klasa - Expando - która w pewien, jak na razie magiczny, sposób pozwala na bardziej naturalne tworzenie dynamicznych obiektów.
groovy> e = new Expando()
===> {}
groovy> e.pole = 1
===> 1
groovy> e.f = { x -> x * pole } // ! nie trzeba specyfikować z jakiego obiektu pochodzi pole, czyli to czego oczekujemy
===> groovysh_evaluate$_run_closure1@174aa60
groovy> e.f(2)
===> 2
groovy> e.pole = 2
===> 2
groovy> e.f(2)
===> 4
Przetestuj poniższy kod, zapamiętaj co się dzieje [ zakładam, że wiesz dlaczego ;) ]
a = [a:1]
e = new Expando()
e.a = 1
e.f = { x -> x * a }
e.f(2)
Więcej o mapach
Brak komentarzy:
Prześlij komentarz