• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Groovy collection api
 

Groovy collection api

on

  • 165 views

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

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

Statistics

Views

Total Views
165
Views on SlideShare
165
Embed Views
0

Actions

Likes
0
Downloads
5
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

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

Groovy collection api Groovy collection api Presentation Transcript

  • Groovy Collection API Trygve Amundsen, Kodemaker
  • basics
  • 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
  • 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]
  • 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
  • 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
  • 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()
  • notation, spread operator assert ["a","b","1"]*.isNumber() == [false,false,true] assert ["a","b","1"].number == [false,false,true]
  • basics, api
  • 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 }
  • 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]
  • 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]
  • 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
  • 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
  • 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"
  • 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
  • inject -> reduce Object.metaClass.reduce = {initial, closure-> delegate.inject(initial, closure) } [1,2,3].reduce(0){acc,val->acc+val}
  • 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 ? 'small' : 'big'} == [small:1, big: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,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]]
  • 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]]
  • 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]]
  • 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]
  • 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 }
  • 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 == [1:['a'], 2:['b','c']]
  • 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!)
  • doc & src
  • Groovy JDK doc
  • Groovy JDK doc
  • DefaultGroovyMethods
  • 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 }
  • more... groovy.codehaus.org meetup.com/Oslo-Groovy-Meetup
  • questions ?
  • Ubrukt
  • 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"]
  • 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() }] }
  • • 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 LinkedHashMap // predictable order ([] as Set) instanceof HashSet (1..3) instanceof IntRange // groovy.lang (1..3) instanceof List