0
Groovy Collection API
Trygve Amundsen, Kodemaker
basics
groovy collections
•
•
•
•
•
•
•

Java Collection (List, Map, Set mfl.)
Array
String
Regexp
Iterable
CharSequence
Object!

...
notation, lists
def emptyList = []
assert [] instanceof ArrayList
def list = [1,2,3]
assert list[1..-1] == [2,3]
assert li...
notation, maps
def emptyMap = [:]
assert [:] instanceof LinkedHashMap // predictable order
assert [a:1, b:2] == ['a':1, 'b...
ranges are lists
assert (1..3) == [1,2,3]
assert (1..<3) == [1,2]

assert (1..3) instanceof IntRange // groovy.lang
assert...
notation, list operators
assert
assert
assert
assert

[1,2] << 3 == [1,2,3]
// leftShift()
[1,2]+3 == [1,2,3]
// plus()
[1...
notation, spread operator
assert ["a","b","1"]*.isNumber() == [false,false,true]
assert ["a","b","1"].number == [false,fal...
basics, api
each
[1,2,3].each { println it}
[1,2,3].each { item -> println item }

[1,2,3].eachWithIndex { item, i -> println "index $...
find (filters)
assert [1,2,3].findAll { it % 2 } == [1,3]
assert [1,2,3].find { it % 2 } == 1

assert [1,2,3].findIndexValue...
collect (map)
assert [1,2,3].collect { it * it } == [1,4,9]

assert [1,[2,3],4].collectNested { it*it } == [1,[4,9],16]
as...
method returns
item content
collect
collectEntries
collectNested

Object

sort
groupBy

findAll
unique
tail
drop/take

stac...
reducers
assert [1,2,3].max() == 3
assert [1,2,3].min() == 1
assert [1,2,3].sum() == 6
assert [1,2,3].max{ -it } == 1
asse...
reducers, cont’d
assert [1,2,3].any{ it > 3 } == false
assert [1,2,3].every{ it < 4 } == true

assert [1,2,3].join(";") ==...
reducers, inject
assert [1,2,3].inject(0)
{ acc, val -> acc+val } == 6
assert [1,2,3].inject("0") { acc, val -> acc+val } ...
inject -> reduce
Object.metaClass.reduce = {initial, closure->
delegate.inject(initial, closure)
}
[1,2,3].reduce(0){acc,v...
useful methods
groupBy, countBy

assert [1,2,3].groupBy{it < 2 ? 'small' : 'big'} == [small:[1], big:[2,3]]
assert [1,2,3].countBy{it < 2...
set operations
assert [1,2]+3 == [1,2,3]
assert [1,2]+[3,4] == [1,2,3,4]
assert [1,2].plus([3,4]) == [1,2,3,4]
assert [1,2...
Nested Collections

assert [1,[2,3],4].flatten() == [1,2,3,4]
assert [1,[2,3],4].collectNested { it+10 } == [11,[12,13],14...
functional style
assert [1,2,3].head() == 1
assert [1,2,3].tail() == [2,3]
assert [1,2,3].first() == 1
assert [1,2,3].last...
list as stack
NOTE: mutates!

def list = [1,2,3]
list.push(4)
assert list == [1,2,3,4]
assert list.pop() == 4
assert list ...
findResults
assert [1,2,3].findResults { it > 1 ? it*it : null } == [4,9]

[1,2,3].findResults { it > 1 ? it*it : null }

i...
Other, possibly useful methods

assert [1,2,3].collectMany { [it**2, it**3] } == [1,1,4,8,9,27]
map withDefault
def newMap = [:].withDefault { [] }
[a:1,b:2,c:2].each { key, val ->
newMap[val] << key
}
assert newMap ==...
mutability
•
•
•
•

all methods return new collections/objects

•

a few exceptions exist, such as push/pop and sort(boole...
doc & src
Groovy JDK doc
Groovy JDK doc
DefaultGroovyMethods
real-world example
params.findAll { key, val ->
// filtrer kun diagnose-parametre
key.startsWith(paramPrefix+"diagnoser")
...
more...
groovy.codehaus.org
meetup.com/Oslo-Groovy-Meetup
questions ?
Ubrukt
sample data
@EqualsAndHashCode @ToString class Person { def name, address, pets }
@EqualsAndHashCode @ToString class Addre...
real-world example
import org.ccil.cowan.tagsoup.Parser
@Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0...
• gå dypt i utvalgte kall, ex
•
•
•
•

groupBy
inject
findResult: find + transform
nested collections: collectNested
Groovy Collection Jdk Doc
• Object
• Object[]
• Collection
• Map
• List
• Set
Basic collection types
assert
assert
assert
assert
assert

[] instanceof ArrayList
// (java.util)
[:] instanceof LinkedHas...
Upcoming SlideShare
Loading in...5
×

Groovy collection api

609

Published on

An overview of groovy's collection api as held on Communities in Action, Oslo, Feb 2012.

Published in: Technology, Education
0 Comments
1 Like
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
609
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
15
Comments
0
Likes
1
Embeds 0
No embeds

No notes for slide
  • merk strings og charsequence
  • Bra for named parameters!
  • Some say thats bad, wtf
  • leftShift == putte inn i - operatoren
  • Ta litt tid hero
    - isNumber er en String operasjon (ikke en collection operasjon)
    - Collections har ikke properties, så variant 2 representerer ikke noen tvetydigheter
  • Trofast, første møtet
    Returnerer ingenting (jo, umodifisert collection)
    Bare en vanlig for-loop, en blindvei på veien mot funksjonell nirvana
    Avhengig av side-effekter for å utføre noe.
  • find burde kanskje hete findFirst
    burde vært en alias for filter - det er det ikke
  • Heter map i mange språk, men collect passer godt i en java-verden
    map henviser jo til noe helt annet
    Veldig nyttig: hvis man vil ha map: bruk collectEntries, returner en array [key, val]
    tygg på navnet: godt navn
  • Fra 30000 fot: bilde!!
  • Reducers - noen kaller det foldLeft, silly :)
    (alle disse tar også transformer/comparator for ikke-standard sammenligning)
  • Dette er lett ;)
    Burde hett reduce. foldLeft i mange språk. foldRight Mangler i groovy.
    Ta litt tid: 1) initial value 2) to understand: closure returns next accumulator
  • Bare mer komplisert. Hva gjør den nullen der? (indikerer at raden skal filtreres bort - ikke akkurat selvforklarende)
    Jeg nevner dette for det ikke står i doken
  • Her er de fleste collection-metoder (+ noen fler) definert resten er i StringGroovyMethods
  • Transcript of "Groovy collection api"

    1. 1. Groovy Collection API Trygve Amundsen, Kodemaker
    2. 2. basics
    3. 3. groovy collections • • • • • • • Java Collection (List, Map, Set mfl.) Array String Regexp Iterable CharSequence Object! assert "string".collect { it } == ['s','t','r','i','n','g'] assert 42.collect { it } == [42] // string
    4. 4. notation, lists def emptyList = [] assert [] instanceof ArrayList def list = [1,2,3] assert list[1..-1] == [2,3] assert list[-3..-2] == [1,2] assert list[2..1] == [3,2]
    5. 5. notation, maps def emptyMap = [:] assert [:] instanceof LinkedHashMap // predictable order assert [a:1, b:2] == ['a':1, 'b':2] method(a:1, b:2) // illusion of named parameters
    6. 6. ranges are lists assert (1..3) == [1,2,3] assert (1..<3) == [1,2] assert (1..3) instanceof IntRange // groovy.lang assert (1..3) instanceof List
    7. 7. notation, list operators assert assert assert assert [1,2] << 3 == [1,2,3] // leftShift() [1,2]+3 == [1,2,3] // plus() [1,2]+[3,4] == [1,2,3,4] [1,2,3]-[3,4] == [1,2] // minus()
    8. 8. notation, spread operator assert ["a","b","1"]*.isNumber() == [false,false,true] assert ["a","b","1"].number == [false,false,true]
    9. 9. basics, api
    10. 10. each [1,2,3].each { println it} [1,2,3].each { item -> println item } [1,2,3].eachWithIndex { item, i -> println "index ${i} contains ${item}" } [1,2,3].reverseEach { println it }
    11. 11. find (filters) assert [1,2,3].findAll { it % 2 } == [1,3] assert [1,2,3].find { it % 2 } == 1 assert [1,2,3].findIndexValues { it %2 } == [0,2]
    12. 12. collect (map) assert [1,2,3].collect { it * it } == [1,4,9] assert [1,[2,3],4].collectNested { it*it } == [1,[4,9],16] assert [1,2,3].collectEntries { ['k' +it, it] } == [k1:1,k2:2,k3:3]
    13. 13. method returns item content collect collectEntries collectNested Object sort groupBy findAll unique tail drop/take stack push/pop max, min, sum, count join inject Collection multiple items one item each eachWithIndex reverseEach find head first/last changed countBy findResults collectMany split plus minus intersect subsequences permutations combinations set boolean unchanged changed number of items unchanged any every
    14. 14. reducers assert [1,2,3].max() == 3 assert [1,2,3].min() == 1 assert [1,2,3].sum() == 6 assert [1,2,3].max{ -it } == 1 assert [1,2,3].max{ a,b-> b<=>a } == 1
    15. 15. reducers, cont’d assert [1,2,3].any{ it > 3 } == false assert [1,2,3].every{ it < 4 } == true assert [1,2,3].join(";") == "1;2;3"
    16. 16. reducers, inject assert [1,2,3].inject(0) { acc, val -> acc+val } == 6 assert [1,2,3].inject("0") { acc, val -> acc+val } == "0123" assert [1,2,3].inject([]) { acc, val -> acc+val } == [1,2,3] assert [a:1,b:2].inject(0) { acc, key, val -> acc+val } == 3
    17. 17. inject -> reduce Object.metaClass.reduce = {initial, closure-> delegate.inject(initial, closure) } [1,2,3].reduce(0){acc,val->acc+val}
    18. 18. useful methods
    19. 19. groupBy, countBy assert [1,2,3].groupBy{it < 2 ? 'small' : 'big'} == [small:[1], big:[2,3]] assert [1,2,3].countBy{it < 2 ? 'small' : 'big'} == [small:1, big:2]
    20. 20. set operations assert [1,2]+3 == [1,2,3] assert [1,2]+[3,4] == [1,2,3,4] assert [1,2].plus([3,4]) == [1,2,3,4] assert [1,2,3]-3 == [1,2] assert [1,2,3]-[2,3] == [1] assert [1,2,3].minus([2,3]) == [1] assert [1,2,3].intersect([3,4]) == [3] assert [1,2,3].disjoint([4,5]) == true assert [1,2,3].subsequences() == [[3], [1, 2, 3], [1], [2], [2, 3], [1, 3], [1, 2]] as Set assert [1,2,3].permutations() == [[1, 2, 3], [2, 3, 1], [3, 2, 1], [3, 1, 2], [2, 1, 3], [1, 3, 2]] as Set assert [[1,2],[3,4]].combinations() == [[1, 3], [2, 3], [1, 4], [2, 4]]
    21. 21. Nested Collections assert [1,[2,3],4].flatten() == [1,2,3,4] assert [1,[2,3],4].collectNested { it+10 } == [11,[12,13],14] assert [['a','b'], [1,2]].transpose() == [['a',1],['b',2]]
    22. 22. functional style assert [1,2,3].head() == 1 assert [1,2,3].tail() == [2,3] assert [1,2,3].first() == 1 assert [1,2,3].last() == 3 assert [1,2,3].take(2) == [1,2] assert [1,2,3].drop(2) == [3] assert [1,2,3].split { it<3 } == [[1,2],[3]]
    23. 23. list as stack NOTE: mutates! def list = [1,2,3] list.push(4) assert list == [1,2,3,4] assert list.pop() == 4 assert list == [1,2,3]
    24. 24. findResults assert [1,2,3].findResults { it > 1 ? it*it : null } == [4,9] [1,2,3].findResults { it > 1 ? it*it : null } is identical to [1,2,3].findAll { it > 1 } .collect { it*it }
    25. 25. Other, possibly useful methods assert [1,2,3].collectMany { [it**2, it**3] } == [1,1,4,8,9,27]
    26. 26. map withDefault def newMap = [:].withDefault { [] } [a:1,b:2,c:2].each { key, val -> newMap[val] << key } assert newMap == [1:['a'], 2:['b','c']]
    27. 27. mutability • • • • all methods return new collections/objects • a few exceptions exist, such as push/pop and sort(boolean mutate) objects and collections are generally mutable use asImmutable(), asSynchronized() for multithreading or better: use gpars (included in groovy jdk) • (that’s a different talk - coming up on groovy meetup!)
    28. 28. doc & src
    29. 29. Groovy JDK doc
    30. 30. Groovy JDK doc
    31. 31. DefaultGroovyMethods
    32. 32. real-world example params.findAll { key, val -> // filtrer kun diagnose-parametre key.startsWith(paramPrefix+"diagnoser") }.groupBy { key, val -> // grupper på rader key.substring(0,"diagnoser[0]".size()) }.findAll { rowKey, rowMap -> // Fjern tomme rader rowMap.any { key, val -> val && val != "null" } }.inject([:]) { acc, key, val -> // ungroup rader (tilbake til en map med parametre) acc + val }.collectEntries { key, val -> // hent sykdomskode.id if (key.endsWith('.sykdomskode') && val) { [key+'.id', Sykdomskode.findByNr(val)?.id ?: ""] } else { [key, val] } }.sort { it.key }
    33. 33. more... groovy.codehaus.org meetup.com/Oslo-Groovy-Meetup
    34. 34. questions ?
    35. 35. Ubrukt
    36. 36. sample data @EqualsAndHashCode @ToString class Person { def name, address, pets } @EqualsAndHashCode @ToString class Address { def street, city } enum Pet { CAT, DOG, BIRD, DUCK } import static Pet.* def persons = [ new Person(name:"Ole", address:new Address(street:"Blindvn 1", city:"Oslo"), pets:[BIRD, CAT]), new Person(name:"Dole", address:new Address(street:"Blindvn 2", city:"Oslo"), pets:[DOG, CAT]), new Person(name:"Doff", address:new Address(street:"Strandvn 9", city:"Bergen"), pets:[BIRD, DOG]), ] assert persons.pets == [ [BIRD, CAT], [DOG, CAT], [BIRD, DOG]] assert persons.pets.flatten().unique() == [BIRD, CAT, DOG] assert persons.address.city.unique() == ["Oslo", "Bergen"]
    37. 37. real-world example import org.ccil.cowan.tagsoup.Parser @Grab(group='org.ccil.cowan.tagsoup', module='tagsoup', version='0.9.7') def gdocHome = "http://groovy.codehaus.org/groovy-jdk/" def gdocs = ["java/lang": ["Object[]","Object"], "java/util": ["Collection", "List", "Map"]] gdocs.inject([:]) { agg, key, val -> // create map of [class:url] agg + val.collectEntries { [it, gdocHome + key+"/"+it+".html" ] } }.collectEntries { className, url -> // parse urls def html = new XmlParser(new Parser()).parse(url) [className, html.body.table[1].tr[1..-1].collect { it.td[1].code.b.a.text() }] }
    38. 38. • gå dypt i utvalgte kall, ex • • • • groupBy inject findResult: find + transform nested collections: collectNested
    39. 39. Groovy Collection Jdk Doc • Object • Object[] • Collection • Map • List • Set
    40. 40. Basic collection types assert assert assert assert assert [] instanceof ArrayList // (java.util) [:] instanceof LinkedHashMap // predictable order ([] as Set) instanceof HashSet (1..3) instanceof IntRange // groovy.lang (1..3) instanceof List
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×