0% found this document useful (0 votes)
30 views

Module 1

This document provides an overview of Groovy fundamentals including the differences between Groovy and Java, data types in Groovy, strings, closures, and other Groovy features. It discusses how Groovy is object-oriented, runs on the JVM, and has a simplified syntax compared to Java while maintaining interoperability. The document also covers key Groovy concepts like operators, collections, and metaprogramming capabilities.

Uploaded by

Ashley Martin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
30 views

Module 1

This document provides an overview of Groovy fundamentals including the differences between Groovy and Java, data types in Groovy, strings, closures, and other Groovy features. It discusses how Groovy is object-oriented, runs on the JVM, and has a simplified syntax compared to Java while maintaining interoperability. The document also covers key Groovy concepts like operators, collections, and metaprogramming capabilities.

Uploaded by

Ashley Martin
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 72

Module 1

Groovy Fundamentals
Module Overview

• Differences between Groovy and Java


• Declaring classes
• Using assertions
• Groovy Strings
• Closures
• Lists and Maps
• Expandos
• Ranges
• Lists, Maps, and Sets
• Builders
• Metaprogramming
Java An Overview

• Object Oriented
• Platform Independent
• Simple
• Secure
• Architecture-neutral
• Portable
• Robust
• Multithreaded
• Interpreted
• High Performance – JIT
• Distributed
• Dynamic
Intro. To Groovy

• OOP
• Through Apache Licence
• Optionally compiled
• Runs in JVM
• Compiles down to Java byte-code
• Simplified syntax
• Support both Static and dynamically typed
• Support for operator overloading.
• operator overloading
• Native syntax for lists and associative arrays
• Native support for regular expressions
• Native support for various markup languages
• You can use existing Java libraries
• Groovy extends the java.lang.Object
Differences between Groovy and Java

• Default imports
• Multi-methods
• Array initializers
• Package scope visibility
• ARM blocks - Automatic Resource Management
• Inner classes
• Static inner classes
• Anonymous Inner Classes
• Creating Instances of Non-Static Inner Classes
• Lambdas
• GStrings
• String and Character literals
• Primitives and wrappers
• Behaviour of ==
• Conversions
• Extra keywords
Default imports

• All these packages and classes are imported by default


• java.io.*
• java.lang.*
• java.math.BigDecimal
• java.math.BigInteger
• java.net.*
• java.util.*
• groovy.lang.*
• groovy.util.*
Multi-methods

• methods which will be invoked are chosen at


runtime.
• Same in Java and Groovy, but it will behave differently:
• int method(String arg) { return 1; }
• int method(Object arg) { return 2; }
• Object o = "Object"; int result = method(o);
Array initializers

• { …​ } block is reserved for closures.


• Unsupported
• int[] array = { 1, 2, 3}
• Supported
• int[] array = [1,2,3]

Package scope visibility

• omitting a modifier on a field doesn‟t result in a


package-private field like in Java:

• Instead, private field, an associated getter and an


associated setter
• to create a package-private field by annotating it
with @PackageScope
Closures

• Following

• Can be written as
Inner classes

• Static inner classes


• Anonymous Inner Classes
• Creating Instances of Non-Static Inner Classes
Static inner classes
Anonymous Inner Classes
Creating Instances of Non-Static Inner Classes

UnSupported Supported
Lambdas

Groovy Java
Java 8 supports lambdas Has Closures
Runnable run = () -> Runnable run = { println
System.out.println("Run 'run' } list.each { println
"); it } // or
list.forEach(System.out: list.each(this.&println)
:println);
Scripting Languages
The old new new thing…

• Productivity / Rapid Development / Agile


• Interpreted (No Compile Cycle)
• Expressive - Shorter, Less Verbose Syntax
• Feature Rich yet Simple and Productive
• Shell / System Integration / Systems “Glue”
• Dynamic
• Open Source – also code available by default
• Advanced languages features Closures / Mix Ins

16
Scripting Languages – Productivity

Productivity - Lines of code compared to C

7
6
5
4
3
2
1
0

lk
va

l
++
C

n
an

r
si

Pe

ho

lta
Ja
C

Ba
r tr

al
t
Py
Fo

Sm
al
su
Vi
S
M

From “Code Complete” by Steve McConnell

17
Scripting Languages – The Reputation

• Weakly Typed
• Procedural
• Scalability / Enterprise Ready
• Not Maintainable – (Perl)
• Lack of threading support
• Lack of IDE / Debugger support
• Cross Platform Support
• Performance
• Specialized / Not general purpose

18
Scripting Languages – The Reality

• The lines are blurring between scripting and


traditionally compiled languages. This trend will
continue.
• Programmer adoption going up, up, up.
• Ruby on Rails, PHP are popular, powerful,
productive and cool.
• Many now target a Java VM‟s (JRuby, Jython,
ABCL) or Perl targets Parrot.
• Optimize developer time over execution time.
• The right tool for the right job.

19
Groovy – In the Sweet Spot

Groovy is feature rich and java friendly

20
Groovy - Overview

• Syntactically very close to Java


• Leverages investment in Java
• Interpreted-ish. .groovy files fully parsed and
classes are generated on the fly, via a custom class
loader.
• Can be compiled and fully integrated with
traditional Java application.
• Language level support for lists, maps, regular
expressions.
• Supports closures, dynamic typing, meta object
protocol.
21
Groovy & Java – Seamless Integration

• Groovy code co-exists with Java Code and runs in


the JRE.
• Syntax nicely aligned with Java.

22
Direct or Precompiled Modes

23
Groovy – Current Situation

• Standards Supported - JSR-241 - Groovy is the


2nd standard language for the Java platform, with
Java being the first.
• Still in Beta – Jsr-6 (released: end of June 2006)
• RC1 – The first release candidate of the Reference
Implementation – was due end of August 2006.
• Pretty stable but wouldn‟t bet my job on it.
• Error messages still hard to decipher.
• Documentation lacking.
• Groovy in Action Book from Manning. 90%
available for download via Early Access Program.

24
Hello World – Groovy Style

println 'Hello Groovy'

To run type „groovy hello.groovy‟


• Parenthesis are optional
• Ending semi-colons optional
• Class declaration optional
• Main entry point optional
• Single Quotes or Double quotes for Strings. Groovy
has several string styles.
• System.out is assumed - Groovy automatically
imports the packages groovy.lang.*, groovy.util.*,
java.lang.*, java.util.*, java.net.*, and java.io.*
25
Groovy Types

• Everything is an object no primitive types.


• Primitive types are auto boxed
• Optional Typing – If not explicitly specified assumed
to be java.lang.Object
• Type safe – Unlike some scripting languages, Groovy
doesn‟t allow one type to be treated as another
without a well defined conversion being available.

26
Types Example

a=1 // Implicit typing to Integer


b = 'howdy' // Implicit typing to String
int c = 33 // Explicit typing to Integer
def d = 5.2f // def keyword means any type

println 'a is ' + a.class.name


println 'b is ' + b.class.name
println 'c is ' + c.class.name
println 'd is ' + d.class.name // class name as
property
Output

a is java.lang.Integer
b is java.lang.String
c is java.lang.Integer
d is java.lang.Float

27
Operator Overloading

Operator Method Operator Method


a+b a.plus(b) a << b a.leftShift(b)
a–b a.minus(b)
a >> b a.rightShift(b)
a*b a.multiply(b)
a >>> b a.rightShiftUnsigned(b)
a/b a.div(b)
a%b a.mod(b) switch(a){
a++ or case b:
++a a.next() } b.isCase(a)
a-- or --a a.previous() a == b a.equals(b)
a**b a.power(b)
a != b ! a.equals(b)
a|b a.or(b)
a <=> b a.compareTo(b)
a&b a.and(b)
a^b a.xor(b) a>b a.compareTo(b) > 0
~a a.negate() a >= b a.compareTo(b) >= 0
a[b] a.getAt(b) a<b a.compareTo(b) < 0
a[b] = c a.putAt(b, c)
a <= b a.compareTo(b) <= 0

28
Strings

• Single Quotes – java.lang.String


• Double Quotes – groovy.lang.GString – Allow
replacement of ${vars}
• Triple Single Quotes – Multi Line Strings, Newlines
always \n, Whitespace preserved.
• Triple Double Quotes – Multi Line GStrings
• Forward Slash – Escape backslashes ignored,
makes Regular Expressions more readable

29
String Example

me = 'Tarzan'
you = 'Jane'
line = "me ${me} - you $you"
assert line == 'me Tarzan - you Jane'
// Note abbrev dollar syntax $you
// Note == is equality not identity

date = new Date(0)


out = "Year $date.year Month $date.month Day $date.date"
assert out == 'Year 70 Month 0 Day 1'
out = "Date is ${date.toGMTString()} !"
assert out == 'Date is 1 Jan 1970 00:00:00 GMT !'
// Note $date.month access month property

30
String Example Continued

// Multi line
sql = """
SELECT FROM MyTable
WHERE Year = $date.year
"""

// Literal dollar sign


out = "my 0.02\$"

// Slashy Strings, don't need to escape


assert "abc" == /abc/
assert "\\d" == /\d/

31
Regular Expressions

• Find Operator: =~
Creates a matcher.
• Match Operator: ==~
Matches a regular expression.
• Pattern Operator: ~String
Creates a pattern from a string.

32
Regular Expression Example

// Find operator
assert "aaa1bbb2ccc3" =~ /bbb/

// Match operator – must match entire string


assert "aaa1bbb2ccc3" ==~ /(...\d)*/

// Patterns
def p = ~/a*b/
assert p instanceof Pattern
def m = p.matcher("aaaaab");
assert m.matches()

33
Ranges

• Specify an upper and lower bound of some


sequence.
• Can be used to replace:
if (a >= 0 && a <= upperBound) {
// do something with a
}

• Ranges are Objects


• lowerbound..upperbound: inclusive
• Lowerbound..<upperbound: half inclusive
• Supports Numbers, Strings, Dates, Reverse
Ranges.
• Can create your own, by overriding next(),
previous() and implements Comparable 34
Ranges Example

assert (0..10).contains(0)
assert (0..10).contains(5)
assert (0..10).contains(10)
assert (0..10).contains(-1) == false
assert (0..10).contains(11) == false
assert (0..<10).contains(9)
assert (0..<10).contains(10) == false
assert ('a'..'c').contains('b')
log = ''

// Replacement for Java for statements.


for (element in 5..9){
log += element
}
assert log == '56789'

35
Lists and Maps

• Groovy has language level support for maps


• Lists specified with [item, item, item] syntax
• java.util.ArrayList under the hood
• Maps specified with [name1:value, name2:value,
name3:value] syntax
• java.util.HashMap under the hood.
• Use [ ] operator to access.
• Define closures to ease iteration.

36
Lists - Specifying

myList = [1,2,3]
assert myList.size() == 3
assert myList[0] == 1
assert myList instanceof ArrayList

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

longList = (0..1000).toList()
assert longList[555] == 555

explicitList = new ArrayList()


explicitList.addAll(myList)
assert explicitList.size() == 3
explicitList[0] = 10
assert explicitList[0] == 10

37
Lists – Overloaded Subscript Operator

myList = ['a','b','c','d','e','f']

assert myList[0..2] == ['a','b','c'] // getAt(Range)

assert myList[0,2,4] == ['a','c','e'] // getAt(Index Collection)

// putAt(Range)
myList[0..2] = ['x','y','z']
assert myList == ['x','y','z','d','e','f']

myList[3..5] = []
assert myList == ['x','y','z']

myList[1..1] = ['y','1','2']
assert myList == ['x','y','1','2','z']

38
Lists – Negative Indexes

• Count from the back of the list. The last index is -1.
• Can be used with ranges.
• list[-3..-1] gives you the last three entries.
• list[1..-2] to cut away the first and the last entry.

39
Lists – Adding and Removing

myList = []

myList += 'a' // plus(Object)


assert myList == ['a']

myList += ['b','c'] // plus(Collection)


assert myList == ['a','b','c']

myList = []
myList << 'a' << 'b' // leftShift is like 'append'
assert myList == ['a','b']

assert myList - ['b'] == ['a'] // Minus to remove

40
Lists – GDK Methods

• Groovy Development Kit adds many methods to


the collection classes.
• Many take closures to perform some operation on
the collection
• Examples: min, max, sort, sum, collect, each, find,
unique etc…

41
Lists Iteration with Closures

def list = [1,2,3]

// Find even numbers


def even = list.find {item -> item % 2 == 0}
assert even == 2

// Is every number less than 5?


assert list.every { item -> item < 5}

// Is any number less than 2


assert list.any { item -> item < 2}

// Append each item to store


def store = ''
list.each { item -> store += item }
assert store == '123'

42
Maps - Specifying

def myMap = [a:1, b:2, c:3]


assert myMap instanceof HashMap
assert myMap.size() == 3
assert myMap['a'] == 1

def emptyMap = [:]


assert emptyMap.size() == 0

def explicitMap = new TreeMap()


explicitMap.putAll(myMap)
assert explicitMap['a'] == 1

43
Maps - Access

def myMap = [a:1, b:2, c:3]

// retrieve
assert myMap['a'] == 1
assert myMap.a == 1
assert myMap.get('a') == 1

assert myMap.d == null


assert myMap.get('d',0) == 0
assert myMap.d == 1 // now it's there

// assign
myMap['d'] = 1
assert myMap.d == 1
myMap.d = 2
assert myMap.d == 2

44
Maps - Iteration

def myMap = [a:1, b:2, c:3]

// Dump contents by each entry


myMap.each {entry ->
println "$entry.key = $entry.value"
}

// Dump contents by each key/value


myMap.each {key, value ->
println "$key = $value"
}

// Dump contents by for


for (key in myMap.keySet())
println "$key = " + myMap[key]

45
Closures

• A powerful and integral feature of Groovy. You won‟t


be able to avoid them.
• Essentially a block of code wrapped in an object.
• Similar to anonymous inner classes in Java but less
verbose and more flexible.
• Aka C# Delegate, Lisp Lambda, C function pointers.
• Useful for iteration, using resources safely.
• Avoids interface proliferation (Runnables, Observers,
Listeners, Visitors, Comparators, Strategies,
Commands, Controllers)
• Have access to local variables without having to
make them final as Java anonymous inner classes
require.
• Proposal from Gosling and others to add Closures
46 to
Closures - Specifying

def list = [1,2,3]

// Closure to print contents of a list


def closure = { x -> println x }
list.each(closure)

// Simplify 1 - Create closure within each


list.each({ x -> println x })

// Simplify 2 - () not required if closure last param


list.each { x -> println x }

// Simplify 3 - 'it' is default parameter name if one param


list.each { println it }

47
Closures - Calling

// Create a closure
def adder = { x, y -> return x + y }

// Call it using the call method


assert adder.call(2, 6) == 8

// Abbreviated call
assert adder(4, 3) == 7

// In a method
void adjustSalary(Closure adjustment) {
for(e in employees) {
adjustment(e)
}
}

48
Groovy Truth

Broader than Java which just uses Boolean tests to determine truth.

Boolean Corresponding boolean value is true

Matcher The matcher has a match

Collection The collection is non-empty

Map Whether the map is non-empty

String The string is non-empty

Number The number is non-zero

None of the above The object reference is non-null

49
Switch Statement

• An object that defines isCase method can be the candidate of a switch


statement.
• All of the standard Java classes have isCase defined.

Object a.equals(b)

Class a.isInstance(b)

Collection a.contains(b)

Range a.contains(b)

Pattern a.matcher(b.toString()).matches()

String (a==null && b==null) || a.equals(b)

Closure a.call(b)

50
Switch Statement Example

switch (10)
{
case 0 : assert false ; break
case 0..9 : assert false ; break
case [8,9,11] : assert false ; break
case Float : assert false ; break
case {it%3 == 0}: assert false ; break
case ~/../ : assert true ; break
default : assert false ; break
}

51
Looping

• Mostly the same as Java.


• Standard Java for not supported.
Use for(x in 0..9) instead
• Enhanced for loop, like Java 5 but uses in rather
than ':' and doesn't requires lists to be templated.
• In many cases, closures can be used instead.

52
Exceptions

• Mostly the same as java with the following


differences.
• Declaration of exceptions in method signatures is
optional. (Even for checked exceptions)
• You therefore don't have to catch checked
exceptions, they just go up the call stack

53
Classes

• Classes defined very much like in Java.


• Public by default
• Default visibility (not public, protected or private)
will automatically adds bean methods.
• Defining member variable type is optional
however can't stand alone.
• Fields can be referenced with subscript operator
myclass['myfield']
• Can also customize the field access operator '.' via
get / set overrides.

54
Class – Field Access

class Counter {
public count = 0
}
def counter = new Counter()

// Using field access operator


counter.count = 1

// using subscript operator


def fieldName = 'count'
counter[fieldName] = 2

55
Class – Overriding Field Access

class PretendFieldCounter {
public count = 0
Object get (String name) { return 'pretend value' }
void set (String name, Object value) { count++ }
}
def pretender = new PretendFieldCounter()

// Call get method via overridden '.' operator


assert pretender.isNoField == 'pretend value'

// Call set method via overriden '.' operator


pretender.isNoFieldEither = 'just to increase counter'
assert pretender.count == 1

56
Method Declaration

• Public by default
• void returns can be omitted
• Types in argument list can be omitted, Object
assumed.
• Dynamic dispatch used to resolve methods.
• Defaults allowed in argument list.
• Optionals parameters if last argument is Object[]
• Common practice to use Maps for 'named'
arguments.

57
Method Example

class Summer {
def sumWithDefaults(a, b, c=0) { return a + b + c }

def sumWithOptionals(a, b, Object[] optionals) {


return a + b + optionals.inject(0) { sum, i -> sum += i }
}

def sumNamed(Map args) {


['a','b','c'].each{ args.get( it, 0 ) }
return args.a + args.b + args.c
}
}
def summer = new Summer()
assert 2 == summer.sumWithDefaults(1,1)
assert 3 == summer.sumWithDefaults(1,1,1)
assert 2 == summer.sumWithOptionals(1,1)
assert 3 == summer.sumWithOptionals(1,1,1)
assert 2 == summer.sumNamed(a:1, b:1)
assert 1 == summer.sumNamed(c:1) 58
Safe Dereferencing

• The ?. operator can be used to safely dereference


member variables without worring about null
pointer exceptions.
• When the reference before that operator is a null
reference, the evaluation of the current expression
stops
def mapand null is returned.
= [a:[b:[c:1]]]

// Normal . operator
assert map.a.b.c == 1

// Safe dereferencing
assert map?.a?.x?.c == null

59
Constructors

• Public by default emp = new Employee()


emp = new Employee(name: 'Bob', age: 32)

• If implicit can class Employee {


def name
construct in 2 ways def age
}
• Empty constructor
• Named params emp = new Employee('Bob', 32)
emp2 = ['Joe', 41] as Employee

• If explicit can
Employee emp3 = ['Tom', 50]

construct in 3 ways class Employee {


Employee(name, age) {
this.name = name; this.age = age
• Traditional Java }
def name
• Using as keyword def age
}
• Implicit type
conversion
60
.groovy Files

• If a .groovy file contains no class, it becomes a


class of type Script using the filename as the class
name. main automatically added.
• If it contains exactly one class with same name as
file, then 1 to 1 relationship as in Java.
• Can contain multiple classes of any visibility
• Can mix scripting code and classes. No need to
worry about ordering. Classes can be referenced
before declared.
• Groovy classloader will search for .groovy files on
the classpath. Will only find classes where name
matches file.
61
Imports

• By default groovy
imports the following
packages into all .groovy
files
• import java.lang.*
• import java.util.*
• import java.io.*
• import java.net.*
• import groovy.lang.*
• import groovy.util.*
• import java.math.BigInteger
• import java.math.BigDecimal

• Import can be usedimport


for thirdparty.Element as
'type aliasing' usingElement2
as
keyword 62
Multimethods

• Groovy takes dynamic type of


arguments into account when
resolving methods. Java uses
static type.
def oracle(Object o) { return 'object' }
def oracle(String o) { return 'string' }

Object x = 1
Object y = 'foo'

assert 'object' == oracle(x)


assert 'string' == oracle(y) // would return 'object' in
Java

63
GroovyBeans

• Allows property access for all JavaBeans, defined


in Java or Groovy. (myclass.myproperty)
• Auto Generates get / set methods for properties
members in groovy classes if member variables
have default visibility.
• Also get / set only generated if you have not
already defined an accessor. This allows you to
create read only or write only properties.

64
GroovyBeans Example

class MyBean implements java.io.Serializable {


String foo, bar
// Make bar read only
String getBar() { return bar }
}

bean = new MyBean(foo: 'foo', bar: 'bar')


println bean.foo
bean.bar = 'error' // this won't be allowed

d = new Date()
println d.time // can access this as a property

65
GroovyBean Properties

• All properties in a bean can be accessed with


property semantics.
class SomeBean {
int var1
String var2
Date var3
}

def bean = new SomeBean(var1: 1, var2: "foo", var3: new


Date());

bean.properties.each { println it.key + " = " + it.value }

66
Spread Dot Operator

• '.*' use to access a property on each element in a


list. Person {
class
Person(def name) { this.name = name }
def name
}

def list = [new Person('Bob'), new Person('Tom'),


new Person('Sal')]

// Java approach
for(Iterator i = list.iterator(); i.hasNext();)
System.out.println(((Person) i).getName());

// Closure
println list.collect{ p -> p?.name }

// Spread dot operator


println list*.name
67
GPath

• GPath is a construction in Groovy code that powers


object navigation, analogous to XPath
• Builds upon bean properties, closures, safe
dereferencing operator and spread dot operator.
// Find all the 'get' methods in this class
println this.class.methods*.name.grep(~/get.*/).sort()

// Output
[getBinding, getClass, getMetaClass, getProperty]

68
GPath Example2

• Given the following model

class Invoice { List items; Date date }

class LineItem {
Product product; int count;
int total() {
return product.dollar * count
}
}

class Product { String name; def dollar}


69
GPath Example2

• You can perform GPath operations like the


following.

// get the totals of all line items in all invoices


invoices.items*.total()

// find all product names with a line item totals > 7000
invoices.items.grep{it.total() > 7000}.product.name

70
Other Topics

• Groovlets – Servlets in Groovy


• GSP – Groovy Server Pages
• Grails – Groovy's version of Ruby on Rails.
• Integrating Groovy – Add groovy macros into your
Java application.
• Lots more XML manipulation – XmlParser,
XmlSlurper
• jUnit support
• Windows / Com scripting via Scriptom

71
Question

You might also like