Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Groovy collection api

1,768 views

Published on

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

Published in: Technology, Education
  • Be the first to comment

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

×