Upload
husain-dalal
View
89
Download
5
Embed Size (px)
Citation preview
Optional parentheses
Optional semicolons
Optional return keyword
Optional public keyword for class
Optional private keyword for method variables
Import
Default imports
import java.lang.*import java.util.*import java.io.*import java.net.*import groovy.lang.*import groovy.util.*import java.math.BigIntegerimport java.math.BigDecimal
Static import aliasing
import static Calendar.getInstance as nowassert now().class == Calendar.getInstance().class
Type [email protected] Calculator { int sum(int x, int y) { x+y }}
@TypeChecked(TypeCheckingMode.SKIP)
http://docs.groovy-lang.org/latest/html/documentation/#_typing
String'a single quoted string'
def aMultilineString = '''line oneline twoline three'''
"a double quoted string"
def fooPattern = /.*foo.*/assert fooPattern == '.*foo.*'
GStringsString name = 'Guillaume' // a plain stringGString greeting = "Hello ${name}"assert greeting.toString() == 'Hello Guillaume'
GString sum = "The sum of 2 and 3 equals ${2 + 3}"assert sum.toString() == 'The sum of 2 and 3 equals 5'
Person person = [name: 'Guillaume', age: 36]assert "$person.name is $person.age years old" == 'Guillaume is 36 years old'
GStrings - Lazydef number = 1 def eagerGString = "value == ${number}"def lazyGString = "value == ${ -> number }"
assert eagerGString == "value == 1" assert lazyGString == "value == 1"
number = 2 assert eagerGString == "value == 1" assert lazyGString == "value == 2"
Number// primitive typesbyte b = 1char c = 2short s = 3int i = 4long l = 5
// infinite precisionBigInteger bi = 6
// primitive typesfloat f = 1.234double d = 2.345
// infinite precisionBigDecimal bd = 3.456
Assigning Numberslong creditCardNumber = 1234_5678_9012_3456Llong socialSecurityNumbers = 999_99_9999Ldouble monetaryAmount = 12_345_132.12long maxLong = 0x7fff_ffff_ffff_ffffLlong alsoMaxLong = 9_223_372_036_854_775_807L
assert 42I == new Integer('42')assert 42i == new Integer('42') // lowercase i more readableassert 123L == new Long("123") // uppercase L more readableassert 2147483648 == new Long('2147483648') // Long type used, value too large for an Integerassert 456G == new BigInteger('456')assert 456g == new BigInteger('456')assert 123.45 == new BigDecimal('123.45') // default BigDecimal type usedassert 1.200065D == new Double('1.200065')assert 1.234F == new Float('1.234')assert 1.23E23D == new Double('1.23E23')assert 0b1111L.class == Long // binaryassert 0xFFi.class == Integer // hexadecimalassert 034G.class == BigInteger // octal
Booleanboolean untypedBooleanVar = false
assert (!true) == false assert (!'foo') == false assert (!'') == true assert (![]) == trueassert (![:]) == trueassert (!0) == true
Listsdef arrayList = [1, 2, 3]assert arrayList instanceof java.util.ArrayList
LinkedList otherLinked = [3, 4, 5]
def letters = ['a', 'b', 'c', 'd']letters << 'e' assert letters[ 4] == 'e'assert letters[-1] == 'e' assert letters[1, 3] == ['b', 'd'] assert letters[2..4] == ['C', 'd', 'e']
def multi = [[0, 1], [2, 3]] assert multi[1][0] == 2
ArraysString[] arrStr = ['Ananas', 'Banana', 'Kiwi']
int[] numArr = [1, 2, 3] assert numArr.size() == 3
Integer[][] matrix2 matrix2 = [[1, 2], [3, 4]]assert matrix2 instanceof Integer[][]
Mapsdef colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']
assert colors['red'] == colors.red
colors['pink'] = '#FF00FF' colors.yellow = '#FFFF00'
assert colors instanceof java.util.LinkedHashMapassert colors.unknown == null
def numbers = [1: 'one', 2: 'two']
def key = 'name'def person = [key: 'Guillaume'] person = [(key): 'Guillaume']
Enumenum State { up, down}
State st = 'up'assert st == State.up
def val = "up"State st = "${val}"assert st == State.up
Arithmetic Operatorsassert 3 / 2 == 1.5 //always BigDecimal. Use intDiv()assert 10 % 3 == 1assert 2 ** 3 == 8
TODO: Find how operators work for BigDecimal
Null check
Safe navigation operator (prevent NullPointerException)
def person = Person.find { it.id == 123 } def name = person?.name assert name == null
Ternary operatorresult = (string!=null && string.length()>0) ? 'Found' : 'Not found'result = string ? 'Found' : 'Not found'
Elvis operator
displayName = user.name ? user.name : 'Anonymous' displayName = user.name ?: 'Anonymous'
Direct field access
Direct field access operator
class User { public final String name User(String name) { this.name = name} String getName() { "Name: $name" } }
User user = new User('Bob')assert user.name == 'Name: Bob' assert user.@name == 'Bob'
Method Pointer
Method pointer operator
String str = 'example of method reference' Closure fun = str.&toUpperCase def upper = fun() assert upper == str.toUpperCase()
def doSomething(String str) { str.toUpperCase() } def doSomething(Integer x) { 2*x } def reference = this.&doSomething assert reference('foo') == 'FOO' assert reference(123) == 246
Pattern Matching
Pattern operator
p = ~'foo' p = ~"foo" p = ~$/dollar/slashy $ string/$ p = ~"${pattern}"
Find operator
String text = "some text to match"Matcher m = text =~ /match/ if (!m) { throw new RuntimeException("Oops, text not found!")}
Match operator
Boolean m = text ==~ /match/
Spread operator
Spread operator
class Car { String make String model}ArrayList<Car> cars = [ new Car(make: 'Peugeot', model: '508'), new Car(make: 'Renault', model: 'Clio')] ArrayList<String> makes = cars*.make assert makes == ['Peugeot', 'Renault']
assert makes*.toUpperCase() == ['PEUGEOT', 'RENAULT']
Spread Operator...int function(int x, int y, int z) { x*y+z}def args = [4,5,6] assert function(*args) == 26
def items = [4,5] def list = [1,2,3,*items,6] assert list == [1,2,3,4,5,6]
def m1 = [c:3, d:4] def map = [a:1, b:2, *:m1] assert map == [a:1, b:2, c:3, d:4]
Operator Overloading...
Range operator
def range = 0..5 assert (0..5).collect() == [0, 1, 2, 3, 4, 5] assert (0..<5).collect() == [0, 1, 2, 3, 4] assert (0..5) instanceof List assert (0..5).size() == 6 assert ('a'..'d').collect() == ['a','b','c','d']
CompareTo() operator
assert (1 <=> 1) == 0assert (1 <=> 2) == -1assert (2 <=> 1) == 1assert ('a' <=> 'z') == -1
Operator Overloading...
Contains() operator OR isCase() operator
def list = ['Grace','Rob','Emmy']assert ('Emmy' in list)
Equals() operator
def list1 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3'] def list2 = ['Groovy 1.8','Groovy 2.0','Groovy 2.3'] assert list1 == list2 assert !list1.is(list2)
Coercion operator asType() method
Integer x = 123
String s = x as String
Operator Overloading...
plus() operator
class Bucket { int size Bucket(int size) { this.size = size } Bucket plus(Bucket other) { return new Bucket(this.size + other.size) }}
def b1 = new Bucket(4)def b2 = new Bucket(11)assert (b1 + b2).size == 15
Type Coercion [asType() method]class Polar { double r double phi def asType(Class target) { if (Cartesian==target) { return new Cartesian(x: r*cos(phi), y: r*sin(phi)) } }}class Cartesian { double x double y}
def polar = new Polar(r:1.0,phi:PI/2)Cartesian cartesian = polar
Date and Time operations
https://groovy.codeplex.com/wikipage?title=Dates%20and%20Times
Multiple Assignmentsdef (int i, String j) = [10, 'foo']assert i == 10 && j == 'foo'
def (_, month, year) = "18th June 2009".split()assert "In $month of $year" == 'In June of 2009'
def (a, b, c) = [1, 2]assert a == 1 && b == 2 && c == null
class Coordinates { double latitude double longitude double getAt(int idx) { if (idx == 0) latitude else if (idx == 1) longitude else throw new Exception("Wrong coordinate index, use 0 or 1") }}
Switch Statementdef x = 1.23def result = ""
switch ( x ) { case "foo": result = "found foo" // lets fall through
case "bar": result += "bar"
case [4, 5, 6, 'inList']: result = "list" break
case 12..30: result = "range" break
still switching.. case Integer: result = "integer" break
case Number: result = "number" break
case ~/fo*/: // toString() representation of x matches the pattern? result = "foo regex" break
case { it < 0 }: // or { x < 0 } result = "negative" break
default: result = "default"}
for in loopfor ( i in 0..9 ) {...for ( i in [0, 1, 2, 3, 4] ) {...
def array = (0..4).toArray()for ( i in array ) {
def map = ['abc':1, 'def':2, 'xyz':3]for ( e in map ) { x += e.value}// iterate over values in a mapfor ( v in map.values() ) {...
def text = "abc"for (c in text) {...
Multi Catchtry { /* ... */} catch ( IOException | NullPointerException e ) { /* one block to handle 2 exceptions */}
A closure in Groovy is an open, anonymous, block of code that can take arguments, return a value and be assigned to a variable.
Closures
Defining Closure{ [closureParameters -> ] statements }
Closure closureNoArg = { println 'Done!' } Closure<String> closureWithOneArgAndExplicitType = { String str -> str.toUpperCase() }assert closureWithOneArgAndExplicitType('groovy') == 'GROOVY'
Closure closureWithTwoArgsAndExplicitTypes = { int a, int b -> a+b }assert closureWithTwoArgsAndExplicitTypes.call(1,2) == 3
Closure closureWithTwoArgAndDefaultValue = { int a, int b=2 -> a+b }assert closureWithTwoArgAndDefaultValue(1) == 3
Closure<Boolean> closureWithBooleanReturn = { File it -> it.name.endsWith('.txt') }
Implicit Paramdef greeting = { "Hello, $it!" }assert greeting('Patrick') == 'Hello, Patrick!'
def greeting = { it -> "Hello, $it!" }assert greeting('Patrick') == 'Hello, Patrick!'
Varargs
def concat1 = { String... args -> args.join('') } assert concat1('abc','def') == 'abcdef'
def multiConcat = { int n, String... args -> args.join('')*n}assert multiConcat(2, 'abc','def') == 'abcdefabcdef'
Delegation
Its a Groovy concept to create Domain Specific Language. http://docs.groovy-lang.org/latest/html/documentation/#_delegation_strategy
String methodsstr = "It's a rainy day in Seattle" str -= "rainy "assert str == “It's a day in Seattle”
---------for(str in 'held'..'helm') { print "${str} " }
held hele helf helg helh heli helj helk hell helm
-------str = 'Groovy is groovy, really groovy' result = (str =~ /groovy/).replaceAll('hip')println result
Groovy is hip, really hip
GString closureclass Person { String name String toString() { name }}def sam = new Person(name:'Sam')def lucy = new Person(name:'Lucy')def p = sam// Create a GString with lazy evaluation of "p"def gs = "Name: ${-> p}"assert gs == 'Name: Sam'p = lucyassert gs == 'Name: Lucy'
List methodslst = [1, 3, 4, 1, 8, 9, 2, 6]total = 0lst.each { total += it }println "Total is $total"
doubled = [] //NOT a good examplelst.each { doubled << it * 2 }println doubled
println lst.collect { it * 2 }[2, 6, 8, 2, 16, 18, 4, 12]
lst = [4, 3, 1, 2, 4, 1, 8, 9, 2, 6]println lst.find { it > 4 }
println lst.findAll { it > 4 }[8, 9, 6]
List methods...lst = ['Programming', 'In', 'Groovy']println lst.collect { it.size() }.sum() //19println lst.inject(0) { carryOver, element -> carryOver + element.size() } //19println lst.join(' ') //Programming In Groovy println lst - ['Productive', 'In'] //[Be, Groovy]
println lst.size() //4println lst*.size() //[2, 10, 2, 6]
Map Methodslangs = ['C++' : 'Stroustrup', 'Java' : 'Gosling', 'Lisp' : 'McCarthy']
langs.each { entry -> println "Language $entry.key was authored by $entry.value"}
println langs.collect { language, author -> language.replaceAll("[+]", "P")}
entry = langs.find { language, author -> language.size() > 3}
println "Found $entry.key written by $entry.value"
Map methods...friends = [ briang : 'Brian Goetz', brians : 'Brian Sletten', davidb : 'David Bock', davidg : 'David Geary', scottd : 'Scott Davis', scottl : 'Scott Leberknight', stuarth : 'Stuart Halloway'] groupByFirstName = friends.groupBy { it.value.split(' ')[0] }groupByFirstName.each { firstName, buddies -> println "$firstName : ${buddies.collect { key, fullName -> fullName }.join(', ')}"}
Brian : Brian Goetz, Brian SlettenDavid : David Bock, David GearyScott : Scott Davis, Scott LeberknightStuart : Stuart Halloway
Closure in methoddef transform(List elements, Closure action) { def result = [] elements.each { result << action(it) } result}String describe(Person p) { "$p.name is $p.age"}def action = this.&describe def list = [ new Person(name: 'Bob', age: 42), new Person(name: 'Julia', age: 35)] assert transform(list, action) == ['Bob is 42', 'Julia is 35']
MemoizationMemoization allows the result of the call of a closure to be cached. If the computation done by a function (closure) is slow, but you know that this function is going to be called often with the same arguments.
def fibfib = { long n -> n<2?n:fib(n-1)+fib(n-2) }assert fib(15) == 610 // slow!
fib = { long n -> n<2?n:fib(n-1)+fib(n-2) }.memoize()assert fib(25) == 75025 // fast!
[optional] CurryingCurrying refers to the concept of partial application. It will let you set the value of one parameter of a closure, and it will return a new closure accepting one less argument.
def nCopies = { int n, String str -> str*n } def twice = nCopies.curry(2) assert twice('bla') == 'blabla' assert twice('bla') == nCopies(2, 'bla')