GROOVY EXPLAINED AS NOTES

 DOING JAVA IN GROOVY STYLE

1-1:Hello, World!

The Groovy version of "Hello, World!" is more easier:

class MyGroovyClass {
    static def main(args){
        println "Hello, World!"
    }
}


1-2:Packages and Classes imported implicitly

Groovy will import the following packages and classes implicitly, so you can use any class in these packages without package prefix:

  • java.lang.*
  • java.util.*
  • java.io.*
  • java.net.*
  • groovy.lang.*
  • groovy.util.*
  • java.math.BigInteger
  • java.math.BigDecimal
BigInteger bi=2

1-3:Syntax simplified

The syntax of Goovy is simplified greatly:

  1. System.out.println => println
  2. System.out.print => print
  3. If the number of arguments is greater than 1, you can omit parenthesis, such as: a.f p1,p2
  4. Return is optional, when it is lost, the value of the last statement will be returned.
  5. Semicolon is optional. But if there are more than one statement in a line, you should use it.
  6. Property, method, Class is automatically public scope.
println "Groovy is cool!"


1-4:Everything is an object

In Groovy, everything is an object, even for java primitive type, such as int, boolean.

1.class == java.lang.Integer

1-5:Floating-point

Groovy uses java.math.BigDecimal for floating-point type, rather than double or float. So the result of the following equation will be false in Java, but will be true in Groovy.

1.1 + 0.1 == 1.2

1-6:How to iterate?

In Groovy, You can iterate in many ways, such as,

  1. len.times{...}
  2. 0.upto(len){...}
  3. for(i in 0..len){...}
  4. 0.step(len, 1){...}

To calculate the sum of the numbers from 1 to 100:

def sum=0
1.upto(100){sum+=it}
sum


1-7:Defining a variable

In Groovy, you can use def to define a variable. Groovy will determine its type in runtime, based on its value. You also can specify the type of variable when you define it, such as int i, the same as Java.

def str=312.3
str.class

1-8:Assert is always working

In Groovy, assert is always working. You needn't and can't use -enableassertions or -ea argument to switch it.

assert 1==1 


1-9:Operator overloadable

Unlike Java, the operators in Groovy are overloadable. For each operator, there is respective method in Groovy. If you want to overload one operator, your works is just to overload its respective method. These operators including:

  1. Comparasion operators, e.g. ==
  2. Alrithmetic operators, e.g. +, - and *
  3. Accessor[]
def map=['tomato':18,'tulip':15]
map['tulip']

1-10:Groovy Truth

In Groovy, condition can work with other types not just Boolean. The Groovy truth(When to be true):

  • Boolean: true
  • Collection: not empty
  • Character: value not 0
  • CharSequence: length greater than 0
  • Enumeration: has more elements
  • Iterator: has next
  • Number: double value not 0
  • Map: not empty
  • Matcher: at least one match
  • Object[ ]: length greater than 0
  • any other types: reference not null
def l=[1]
(!l) == false

1-11:Closure

In one word, in Groovy, Closure is a code block. It can be invoked as functions and passed as arguments.

def echo = { it -> return it }
echo("Hello, Closure!") == "Hello, Closure!"

1-12:Duck Typing

Duck typing does not mean non-type or weak-type. It is checked at runtime not compile time. And, it is to check its behaviors not its type.

That is "if it walks like a duck and talks like a duck, it's probably a duck.".

class Man{
    def showMe(){
        "Man"
    }
}
class Woman{
    def showMe(){
        "Woman"
    }
}
def takeMe(me){
    me.showMe()
}
assert takeMe(new Man()) == "Man"
assert takeMe(new Woman()) == "Woman"

1-13:GroovyBean

GroovyBean is similar to JavaBean, but there are some differences between them:

  • The default scope of members is public.
  • What you defined is properties, not fields.
  • You don't have to write getter/setter.
  • If you access properties, Groovy will invoke the getter/setter of that propery.
  • You can use “obj.@prop”to access the field behind the property.
  • You can use “new ClassName(prop1: valueOfProp1, prop2: valueOfProp2...) to initialize a class.
class MyGroovyBean{
    String prop1
    int prop2
}

def mgb= new MyGroovyBean(prop1: "This is a GroovyBean.", prop2: 2)
mgb.prop1 == "This is a GroovyBean."

1-14:== operator

In Java, == operator is for identity. While in Groovy, this operator is for equality. That is, if you use == operator, Groovy will translate it into an invocation of equals method.

def str1 = "groovy" 
def str2 = new String("groovy")
str1 == str2

1-15:is method

In Groovy, you can use is method to determine whether two objects are the same instance, unlike java.

def str1 = "groovy" 
def str2 = new String("groovy")
str1.is(str2) == false


1-16:as operator

In Groovy, as operator has two usages:

1. To define the alias of an imported class, such as

import java.lang.Math as M 
M.log10(100)

2. For type-casting, such as

def i = '123' as int

If a Class implemented asType(Class) method, you can use as operator on it.

'123' as int == 123


1-17:?. operator

In Groovy, you can use ?. operator to avoid NPE(Null Pointer Exception). The result of object?.method is:

  • if object = null, then result = null。
  • if object != null, then result = object.method
def l= null // l is a list
l?.size() == null


1-18:Spaceship operator

If you implement a comparator in Java, you could implement it this way:

public int compare(int arg1, int arg2) {
    if (arg1 == arg2) return 0;
    else if (arg1 < arg2) return -1;
    else return 1;
}

As a Groovy programmer, you can use spaceship operator:

int compare(int arg1,int arg2){
    arg1<=>arg2
}
assert compare(2,2) == 0
assert compare(1,2) == -1
assert compare(3,2) == 1


1-19:.& operator

You can use .& operator to refer to a method as a closure, then you can use it as a closure.

def show(n){
    println n
}
[1, 2, 3, 4].each(this.&show)


1-20:Elvis operator

Elvis operator(?:) in Groovy is a simplified form of ternary operator.

def flower= "tulip"
(flower ?: "unknown") == ((flower)? flower : "unknown")



STRINGS SONG

2-1:Declaring a String

There are three ways to declare a String in Groovy :

1. '......'

e.g. 'Hello'

2. "......"

e.g. "Hello"

3. ''' Multi-lines ''' or """ multi-lines """

e.g. """11111
          22222""""

def str="I'm a String!"


2-2:+ operator

You can use + operator to concate Strings:

"1+2" + "=3" == "1+2=3"

2-3:- operator

Subtracting string A from string B will remove the first substring(which matches the string A) in string B :

"It's a rainy day!" - " rainy" == "It's a day!"

2-4:Reversing a String

You can use reverse method to make a string in reverse order.

'lip'.reverse() == 'pil'

2-5:GString

GString is a String including expression, which syntax is similar to JSP EL.

def count= 25
"I have ${count} flower pots."

2-6:Using String as iteration range

String can also be iteration range as what number does:

for(str in 'aa'..'ab' ){
    println str
}

Be careful, the characters in these two strings must be the same but the last one. That is, 'ab'..'ab' and 'aaa'..'aaz' are ok, but 'aa'..'bb' and 'aaa'..'abc' are not.

2-7:Used as a char array

String can be used as a char array:

def str='321'
str[1] == '2'

2-8:Declaring a regular expression

The groovy way of decalring a regular expression:

  • ~'...' or ~"...", it is noted that there is no space between ~ and the string following it
  • /.../, in this way, you don't have to escape backslash
/(F|f)lower/

2-9:Matching a regular expression

In Groovy, you can use =~ or ==~ operator to match a regular expression. The difference between them is  ==~ operator is more restrictive. ==~ means the whole string must match the expression, and =~ means the part of string matches the expression.

assert !('flower or vegetable' =~ /(F|f)lower/) == false
assert ('flower or vegetable' ==~ /(F|f)lower/) == false

2-10:Replacement

You can use a regular expression for replacement of String.

str = "I'm a student."
result = (str =~ /student/).replaceAll('driver')


NUMBERS GAME

3-1:Adaptive Integer Type

Groovy will choose the most appropriate Integer Type based on its value.

3000000000.class

3-2:** operator

** operator is power operator, such as a**b, which means "the bth power of a", where the type of a and b are both Number.

2**3

3-3:times method

times method can be used for iteration, which means "the iteration times":

3.times{
    println it
}


3-4:upto/downto method

These two methods both can be used for iteration. They specify the start and end of iteration.

3.upto(5){
    println it
}

3-5:step method

step defines the start point and the end point of iteration, and specifies the step length of each iteration. "a.step(b,c)" means that "from a up to b, the step increment used in each iteration is c".

lst= []
1.step(9.5, 2.5){
    lst<< it
}
lst



COLLECTION ENHANCED

4-1:Building up a List

In Groovy, building up a List is easier:

def lst = [1,2,3]

4-2:Getting elements from a List

You can use two ways to get elements from a List:

  • With index, which is 0-based. If index >=0, you will get indexth element from beginning; if index < 0, you will get the indexth element from ending. "-1" means "the last one".
  • With Range, you will get a sublist of a List
def l= [1,2,3,4]
assert l[2] == 3
assert l[-1] == 4
assert l[1..2] == [2,3]

4-3:Constructing a Map

You can construct a map in Groovy like this:

def map= ['width':18, 'height':20]

4-4:Adding a element to a Map

How to put an element into a Map:

  • map[key]=value
  • map.put(key:value)
def map= [:]
map['length']=15
map

4-5:Getting elements from a Map

The groovy way to get elements from a Map with a key:

  • map.key
  • map[key]
  • map.get(key) 
['width':18, 'height':20].width

4-3:Constructing a Map

You can construct a map in Groovy like this:

def map= ['width':18, 'height':20]

4-4:Adding a element to a Map

How to put an element into a Map:

  • map[key]=value
  • map.put(key:value)
def map= [:]
map['length']=15
map

4-5:Getting elements from a Map

The groovy way to get elements from a Map with a key:

  • map.key
  • map[key]
  • map.get(key) 
['width':18, 'height':20].width

4-6:Removing elements from a Map

You can use remove method to erase an element from a Map.

def map=['width':18, 'height':20,'length':15]
map.remove('width')
map

4-7:The list in a Map

In a Map, you can use map.keySet() and map.values() to get a key list and a value list:

['width':18, 'height':20,'length':15].keySet().sort()

4-8:Declaring a Range

Range is a new kind of Collection introduced by Groovy, it defines the range of iteration. You can define a Range as:

  • A..B defines all values between A and B, including A and B.
  • A..<B defines all values between A and B, including A but B.
def range=1..10

4-9:from/to of a Range

You can use from/to to get the beginning and ending of a Range.

def range = 1..10
range.from+"**"+range.to

4-10:<< operator

Adding an element to a List, you can use << operator.

def l=[]
l << 1
l << 2
l << 3
assert l == [1,2,3]

4-11:each method

You can use each method to iterate a Collection, and the element of the Collection will be passed to the closure agrument of this method in each iteration. The code is like:

    list.each{ e -> ...}

For Map, there is another each mehod(k and v  means key and value respectively):

    map.each{ k, v -> ...}
def total=0
[1, 3, 8, 2, 6].each{total += it }
total

4-12:collect method

collect method is similar to each method, the difference is the result of each iteration will be put into a new Collection. At the end of last iteration, this collection will be returned.

map=['width':18, 'height':20,'length':15]
map.collect{ key, value ->
    key.toUpperCase()
}

4-13:find method

You can use find method to find an element in a collection. This method will find the first elmenet met need, you can use findAll to get all elements.

[1, 3, 8, 2, 6].find { it > 3 }

4-14:join method

You can use join method to concate all the elements in a list as a string, using the string passed to this method as seperator between elements. This method also can be applied to a range.

[1, 3, 8, 2, 6].join('--')

4-15:rever method

Similar to String, List also has reverse method, which can be applied to a range too.

[1, 3, 8, 2, 6].reverse()

4-16:reverseEach method

You can use reverseEach to iterate a collection in reverse order.

def lst1 = [1,2,3]
lst1.reverseEach{
    println it
}

4-17:eachWithIndex method

This method is a each method passing element and its index to the closure.

def lst=[3,2,1]
def map=[:]
lst.eachWithIndex{value,index->
    map[value]=index
}
map

4-18:findIndexOf method

This method will find the index of the element meeting condition, which is given by a closure. This method has two forms:

  • Finding from beginning, findIndexOf(Closure)
  • Finding from the given index, findIndexOf(startIndex, Closure)
[3,2,1].findIndexOf{ it in [2] }

4-19:sum method

You can use sum to calculate the sum of a collection, which will apply + operator to each item.

[3,2,1].sum()

4-20:inject method

inject method will inject an initial value to a closure in the first iteration, and then it will pass the result of previous closure to the next closure. Usage: list.inject(arg){arg,item->...}.

//The initial value of s is 0, injected by this method
[1, 2, 3].inject(0){ s, item -> s += item }

4-21:*. operator

When you are invoking spread operator(*. operator) on a collection, you are invoking a method on each collection item, and all the result of these invocation will be organized as a collection to return.

def list = ['groovy', 'scala', 'clojure']
list*.reverse() == list.collect{it.reverse()}

4-22:flatten method

flatten method flattens a collection, all the items in that collection will be in a new collection to return. There is no embeded collection in the new collection.

[[1,2],3,4].flatten()

4-23:groupBy method

When you want to group the items in a collection, you can use groupBy method.

def map=['tulip':23,'tomato':34,'lilly':35]
map.groupBy{it.value>25}

4-24:max/min method

max/min method can be used to find the maximum/minimum in a collection.

[1,3,8,2,6].max()

4-25:unique method

unique method will remove all duplicate items in a collection.

def lst= [3,2,3,3,1,5]
lst.unique()

4-26:sort method

sort method can sort a collection, such as l.sort(). You also can give a closure as a comparator.

def l= [1,3,8,2,6].sort{a, b ->
    b <=> a
}
l == [8,6,3,2,1]

4-27:every method

If you want to know whether all the items in a collection meet a condition, you can use every method. The return value is a boolean value.

[1,3,8,2,6].every{it>0}

4-28:any method

If you want to know whether there is any item in a collection meet a condition, you can use any method. Its result is a boolean value.

[1,3,8,2,6].any{it>3}


DATE MATTERS

5-1:+ operator

In Groovy,you can add days to Date:Date + days。

def today= new Date()
(today + 1).day - today.day == 1

5-2:- operator

In Groovy, you can apply minus to Date: "Date - days" or "Date - Date".

def today= new Date()
today - today == 0

5-3:Comparing Date

You can use after and before method to compare two Dates. And the more groovier way is to use comparasion operator.

def today= new Date()
(today+1) > today

5-4:Increment and Decrement of a Date

You can use previous and next method to decrement and increment a Date.

def today = new Date()
def d1= today.day
def d2= today.previous().day
d1-d2 == 1

5-5:Formatting a Date

Date has a format method which you can use to format a Date:

println new Date().format("yyyy-MM-dd")



SIMPLIFIED BEAN


6-1:Properties and Fields

In GroovyBean, what you are defining actually is properties not fields. When you access it, Groovy will invoke its default getter/setter automatically:

  • a.b=…   // invoking a.setB
  • …=a.b   // invoking a.getB

If you want to have your own getter/setter, just do it. The way is the same as java —— implementing your getter/setter.

If you want to get the value of the field, you can use.@ operator: a.@b, this actually accesses the field behind of property b.

class A{
    def b
    def getB(){
        return 'B'
    }
}
def a = new A(b:'b')
assert a.b == 'B'
assert a.@b == 'b'

6-2:GPath

Accessing Object, you can use GPath. For nested object, you also can use GPath. It looks like: "Obj.prop".

class A{
    def p
}
class B{
    def p1
    A   p2
}
def a= new A(p:'China')    
def b= new B(p1:"Xi'an", p2:a)    
b.p1 + ", "+ b.p2.p == "Xi'an, China"


WRITE CODE IN CLOSURES

7-1:Introduction

Closure is a code block. You can give it a name and pass it everywhere or invoke it as a function. This is what it looks: {code block}. When invoking a closure, you also can pass some arguments to it like you are calling a function.

def square = {it * it}
square(5)

7-2:Calling a closure

You can invoke a closure using "closure.call(args)", "call" can be ignored, so you can use "closure(args)" directly.

def add = { arg1, arg2-> arg1+arg2}
add 1, 

7-3:Implicit argument

If a closure has only one argument, you don't have to declare it, and you can refer to this argument with "it".

def echo = { return it }
echo("Hello, Closure!") == "Hello, Closure!"

7-3:Implicit argument

If a closure has only one argument, you don't have to declare it, and you can refer to this argument with "it".

def echo = { return it }
echo("Hello, Closure!") == "Hello, Closure!"

7-5:curry()

When you curry a closure, you will get a new closure with prebinded parameters. It is convenient to apply curry method to a closure with many parameters most of which are always not changed.

Be careful, curry only bind preceding parameters, that is, if a closure has 3 parameters: p1, p2, p3, curry will bind p1 or "p1,p2". And "p1,p3" is not allowed.

def multiple = { x, y -> x*y }
def twice = multiple.curry(2)
twice(3)

7-6:Passed as a parameter

Closure can be passed around as a parameter.

def repeat(n, c){
  n.times{
    c()
  }
}
repeat(10, {print '*'})

If Closure is the type of the last parameter of a function, you can write it like this:

repeat(10){print '*'}










Comments

Popular posts from this blog

Conversion from Clob To String in java and Vice versa

Portable Java 8/ JDK8 setup without admin rights

Multi Threading , Producer consumer problem in Java