working with groovy collections

34
Ted Vinke First8 September 2015 COLLECTIONS groovyCollections.each { “working with $it” }

Upload: ted-vinke

Post on 17-Jan-2017

257 views

Category:

Software


2 download

TRANSCRIPT

Page 1: Working with Groovy Collections

Ted VinkeFirst8 September 2015

COLLECTIONSgroovyCollections.each { “working with $it” }

Page 2: Working with Groovy Collections

Overview• Java Collections Basics

• Iterable & Collection• Groovy Makes Things Easy

• List, Set, Range, Map• GDK’s Iterable & Collection

• Some examples• collate, collect, collectEntries, every and any, find,

findResults, groupBy, inject, removeAll, sum• References

Page 3: Working with Groovy Collections

JAVA COLLECTIONS BASICSWhere it all starts

Page 4: Working with Groovy Collections

Java Collections

Page 5: Working with Groovy Collections

Iterable interface• iterator

Iterator interface• hasNext• next• remove

Page 6: Working with Groovy Collections

Collection interface• add• addAll• clear• contains(Object)• containsAll(Collection)• isEmpty• iterator• remove• removeAll• retainAll• size• toArray

Page 7: Working with Groovy Collections

GROOVY MAKES THINGS EASY

Page 8: Working with Groovy Collections

Groovy Makes Things Easy• Creating a collection

• list = new ArrayList() vs list = []• map = new HashMap() vs map = [:]

• Working with elements• Addition e.g. list.add(3) vs list << 3• Retrieval e.g. map.get('color') vs map.color

• Overloading• list1.addAll(list2) vs list1 + list2

Page 9: Working with Groovy Collections

Listdef list = ['a', 'b']list << 'c'assert list.size() == 3assert list.get(0) == 'a'assert list instanceof java.util.List

def emptyList = []assert emptyList.size() == 0

List is an ordered collection of elements

Page 10: Working with Groovy Collections

Setdef list = ['a', 'b']list << 'c'list << 'c'assert list.size() == 4

def set = list as Setassert set.size() == 3assert set instanceof java.util.Set

Set is a collection with no duplicates

Page 11: Working with Groovy Collections

Rangedef range = 5..8assert range.size() == 4assert range[2] == 7assert range instanceof java.util.List

range = 'a'..'d'assert range.size() == 4assert range[2] == 'c'assert range.from == 'a'assert range.to == 'd'

Range is an extension of List

Page 12: Working with Groovy Collections

Mapdef map = [name: 'Ted', age: 34]map.color = 'blue'assert map.size() == 3assert map['name'] == 'Ted'assert map instanceof java.util.Map

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

Map maps keys to values – e.g. a dictionary.

No duplicate keys.

Page 13: Working with Groovy Collections

Tip: def“The keyword def is

great for examples, but not always so much for

real API design.”

Page 14: Working with Groovy Collections

IT’S NOT ONLYSYNTACTIC SUGAR

Page 15: Working with Groovy Collections

addAll, addAll, addAll, asBoolean, asImmutable, asSynchronized, asType, collect, collect, collect, collectNested, each, eachWithIndex, find, find, findAll, findAll, findResult,findResult, flatten, getAt, getIndices, grep, grep, inject, inject, intersect, isCase, leftShift, minus, plus, plus, plus, removeAll, removeAll, removeElement, retainAll, retainAll,split, toListString, toListString, toSet, unique, unique, unique, unique, unique, unique Groovy’s Collection

Page 16: Working with Groovy Collections

any, asCollection, asList, collate, collate, collate, collate, collectEntries, collectEntries, collectEntries, collectEntries, collectMany, collectMany, collectNested,collectNested, combinations, combinations, contains, containsAll, count, count, countBy, disjoint, drop, dropRight, dropWhile, each, eachCombination, eachPermutation,eachWithIndex, every, findResults, first, flatten, flatten, getAt, groupBy, groupBy, groupBy, head, indexed, indexed, init, intersect, join, last, max, max, max, min, min, min, minus,minus, multiply, permutations, permutations, plus, plus, size, sort, sort, sort, sort, sort, sum, sum, sum, sum, tail, take, takeRight, takeWhile, toList, toSet, toSorted, toSorted,toSorted, toSpreadMap, toUnique, toUnique, toUnique, withIndex, withIndex

Groovy’s Iterable

Page 17: Working with Groovy Collections

SOME EXAMPLES

Page 18: Working with Groovy Collections

collatedef names = ["Lassy", "Buttercup", "Carmella", "Moo-moo", "Cinnamon"]

// collate into batches of 3def collated = names.collate 3assert collated == [['Lassy', 'Buttercup', 'Carmella'], ['Moo-moo', 'Cinnamon']]

// and passing a step of 1collated = names.collate 3, 1assert collated == [['Lassy', 'Buttercup', 'Carmella'], ['Buttercup', 'Carmella', 'Moo-moo'], ['Carmella', 'Moo-moo', 'Cinnamon'], ['Moo-moo', 'Cinnamon'], ['Cinnamon']]

Page 19: Working with Groovy Collections

Remember closures?

def adder = { a, b -> print a+b }assert adder(1, 2) == 3assert adder("m", "e") == "me"

Page 20: Working with Groovy Collections

Closures are used a lot!• e.g. basic looping

• dogs.each { it.bark() }• names.each { name ->

println “Hello $name”}

• or whatever the methods’ Javadoc says

Page 21: Working with Groovy Collections

collectdef animals = []animals << new Animal(name: "Buttercup", age: 2)animals << new Animal(name: "Carmella", age: 5)animals << new Animal(name: "Cinnamon", age: 2)

// collect on Listdef names = animals.collect { it.name }assert names == ["Buttercup", "Carmella", "Cinnamon"] // names is java.util.ArrayList

// collect as a different type e.g. a Set, keeping only unique valuesassert animals.collect(new HashSet()) { it.age }.toString() == "[2, 5]"

Page 22: Working with Groovy Collections

collectEntriesdef john = new Farmer(name: "John")def dick = new Farmer(name: "Dick")

def animals = []animals << new Animal(name: "Buttercup", farmer: john)animals << new Animal(name: "Carmella", farmer: dick)animals << new Animal(name: "Cinnamon", farmer: dick)

// collect farmer name by animal namedef results = animals.collectEntries { animal -> [animal.name, animal.farmer.name]}assert results == ['Buttercup':'John', 'Carmella':'Dick', 'Cinnamon':'Dick']

Page 23: Working with Groovy Collections

every and anydef animals = []animals << new Animal(name: "Buttercup", age: 2)animals << new Animal(name: "Carmella", age: 5)animals << new Animal(name: "Cinnamon", age: 2)

// check if all animals are youngboolean allAreYoung = animals.every { it.age < 3 } assert !allAreYoung // Carmella is, with age 5, not young

// check if atleast one of them is youngboolean atleastOneIsYoung = animals.any { it.age < 3 }assert atleastOneIsYoung // Buttercup and Cinnamon are both young enough

Page 24: Working with Groovy Collections

finddef animals = []animals << new Animal(name: "Buttercup", age: 2)animals << new Animal(name: "Carmella", age: 5)animals << new Animal(name: "Cinnamon", age: 2)

// find first matching animal Animal foundAnimal = animals.find { it.age == 2 }assert foundAnimal.name == "Buttercup"

// find all matching animalsList foundAnimals = animals.findAll { it.name.startsWith "C" } assert foundAnimals.toString() == "[Carmella, Cinnamon]"

Page 25: Working with Groovy Collections

findResultsdef animals = []animals << new Animal(name: "Buttercup", age: 2)animals << new Animal(name: "Carmella", age: 5)animals << new Animal(name: "Cinnamon", age: 2)

// find all non-null resultsdef greetings = animals.findResults { it.age < 4 ? "Hello $it.name!" : null} assert greetings == ['Hello Buttercup!', 'Hello Cinnamon!']

Page 26: Working with Groovy Collections

groupBydef animals = []animals << new Animal(name: "Buttercup", country: "NL", age: 2)animals << new Animal(name: "Carmella", country: "NL", age: 5)animals << new Animal(name: "Cinnamon", country: "BE", age: 2)

// single closureMap animalsByCountry = animals.groupBy { it.country }assert animalsByCountry["NL"].size() == 2 // Buttercup and Carmellaassert animalsByCountry.BE.size() == 1 // Cinnamon

// list of closuresMap animalsByCountryAndAge = animals.groupBy( [{ it.country }, { it.age }] ) assert animalsByCountryAndAge.toString() == "[NL:[2:[Buttercup], 5:[Carmella]], BE:[2:[Cinnamon]]]"

Page 27: Working with Groovy Collections

injectdef animals = []animals << new Animal(name: "Buttercup", price: 2, farmer: "john")animals << new Animal(name: "Carmella", price: 5, farmer: "dick")animals << new Animal(name: "Cinnamon", price: 2, farmer: "dick")

// iteration, passing 1st item to closure, injecting results back into closure with 2nd item, etcassert 1 * 2 * 3 * 4 == [1, 2, 3, 4].inject { current, val -> current * val }

// gather the total price of all animals, passing initial price of 0assert 9 == animals.inject(0) { totalPrice, animal -> totalPrice + animal.price }// or...assert 9 == animals.price.inject(0) { totalPrice, price -> totalPrice + price}

Page 28: Working with Groovy Collections

removeAlldef animals = []animals << new Animal(name: "Buttercup", age: 2)animals << new Animal(name: "Carmella", age: 5)animals << new Animal(name: "Cinnamon", age: 2)

// remove all animals younger than 3animals.removeAll { it.age < 3 }assert animals.size() == 1assert animals.first().name == "Carmella"

Page 29: Working with Groovy Collections

sumdef animals = []animals << new Animal(name: "Buttercup", price: 2, farmer: "john")animals << new Animal(name: "Carmella", price: 5, farmer: "dick")animals << new Animal(name: "Cinnamon", price: 2, farmer: "dick")

// gather the total price of all animalsassert 9 == animals.sum { it.price }assert 9 == animals.price.sum()

Page 30: Working with Groovy Collections

MAKING COMBINATIONS

Page 31: Working with Groovy Collections

Animals by farmer// groupingdef animalsByFarmer =

animals.groupBy { it.farmer }

assert "[john:[Buttercup], dick:[Carmella, Cinnamon]]" == animalsByFarmer.toString()

Page 32: Working with Groovy Collections

Total price per farmer// grouping, collecting and summingdef totalPriceByFarmer = animals .groupBy { it.farmer } .collectEntries { k, v -> [k, v.price.sum()] }assert ['john':2, 'dick':7] == totalPriceByFarmer

Page 33: Working with Groovy Collections

Tip: sort mutatesdef animalList = createAnimals([])assert animalList instanceof java.util.ArrayListassert animalList.name == ["Lassy", "Buttercup", "Moo-moo"]

List sortedByAge = animalList.sort { it.age }assert animalList.name == ["Moo-moo", "Lassy", "Buttercup"]assert sortedByAge.name == ["Moo-moo", "Lassy", "Buttercup"]assert animalList.is(sortedByAge) // is() is same as == in plain Java

def animalSet = createAnimals([] as Set)assert animalSet instanceof java.util.HashSet

List sortedByName = animalSet.sort { it.name }assert sortedByName.name == ["Buttercup", "Lassy", "Moo-moo"]assert animalSet != sortedByNameassert !animalSet.is(sortedByName)

List againAnimalList = createAnimals([])// pass false as the 1st parameter to indicate NOT to mutate original ListList againSortedByAge = againAnimalList.sort(false) { it.age }assert againAnimalList.name == ["Lassy", "Buttercup", "Moo-moo"]assert againSortedByAge.name == ["Moo-moo", "Lassy", "Buttercup"]

def createAnimals = { c -> c << new Animal(name: "Lassy", age: 2) c << new Animal(name: "Buttercup", age: 3) c << new Animal(name: "Moo-moo", age: 1) c}

Page 34: Working with Groovy Collections

References• Oracle Java™ Tutorials: Collections Trailhttps://docs.oracle.com/javase/tutorial/collections/index.html

• The Groovy Dev Kit: Working with Collectionshttp://groovy-lang.org/groovy-dev-kit.html#_working_with_collections

• Groovy Closureshttp://groovy-lang.org/closures.html