SlideShare a Scribd company logo
From Java to Groovy:
Adventure Time!
Iván López @ilopmar
➢ Iván López @ilopmar
➢ Groovy & Grails
developer
➢ @MadridGUG
coordinator
➢ Greach organizer
@greachconf
http://greachconf.com
➢ Speaker: SpringOne 2GX, GR8Conf,
GGX, Codemotion, GeeCon, jDays,
Spring IO, Greach, ConFoo, ConFess,
RigaDevDays...
About me...
1.
What is Groovy?
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
“Apache Groovy is a powerful, optionally typed and dynamic
language, with static-typing and static compilation capabilities,
for the Java platform aimed at improving developer
productivity thanks to a concise, familiar and easy to learn
syntax.
It integrates smoothly with any Java program, and immediately
delivers to your application powerful features, including
scripting capabilities, Domain-Specific Language authoring,
runtime and compile-time meta-programming and functional
programming.
– Groovy website
Groovy
2.
Why not Java?
➢ Java is solid
➢ Known by a lot of developers
➢ Used everywhere
➢ Is fast
But...
➢ Java is verbose
➢ Can be annoying
➢ It's not dynamic
Why not Java?
3.
Making Java Groovy
Greeter.java
public class Greeter {
private String greeting;
public void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names);
System.out.println(helloMessage);
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
private String prepareHelloMessage(String... names) {
String delimiter = "";
StringBuilder sb = new StringBuilder();
for (String name : names) {
sb.append(delimiter).append(name);
delimiter = ", ";
}
return this.greeting + " " + sb.toString() + "!";
}
public static void main(String[] args) {
final Greeter greeter = new Greeter();
greeter.setGreeting("Hi");
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard");
}
}
Rename
public class Greeter {
private String greeting;
public void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names);
System.out.println(helloMessage);
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
private String prepareHelloMessage(String... names) {
String delimiter = "";
StringBuilder sb = new StringBuilder();
for (String name : names) {
sb.append(delimiter).append(name);
delimiter = ", ";
}
return this.greeting + " " + sb.toString() + "!";
}
public static void main(String[] args) {
final Greeter greeter = new Greeter();
greeter.setGreeting("Hi");
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard");
}
}
Greeter.groovy
Groovy
public class Greeter {
private String greeting;
public void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names);
System.out.println(helloMessage);
}
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
private String prepareHelloMessage(String... names) {
String delimiter = "";
StringBuilder sb = new StringBuilder();
for (String name : names) {
sb.append(delimiter).append(name);
delimiter = ", ";
}
return this.greeting + " " + sb.toString() + "!";
}
public static void main(String[] args) {
final Greeter greeter = new Greeter();
greeter.setGreeting("Hi");
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard");
}
}
optional
public class Greeter {
private String greeting
public void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
System.out.println(helloMessage)
}
public String getGreeting() {
return greeting
}
public void setGreeting(String greeting) {
this.greeting = greeting
}
private String prepareHelloMessage(String... names) {
String delimiter = ""
StringBuilder sb = new StringBuilder()
for (String name : names) {
sb.append(delimiter).append(name)
delimiter = ", "
}
return this.greeting + " " + sb.toString() + "!"
}
public static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.setGreeting("Hi")
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
optional
Groovy
verbose
getter/setter
Groovy
class Greeter {
private String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
System.out.println(helloMessage)
}
String getGreeting() {
return greeting
}
void setGreeting(String greeting) {
this.greeting = greeting
}
private String prepareHelloMessage(String... names) {
String delimiter = ""
StringBuilder sb = new StringBuilder()
for (String name : names) {
sb.append(delimiter).append(name)
delimiter = ", "
}
return this.greeting + " " + sb.toString() + "!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.setGreeting("Hi")
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
System.out.println(helloMessage)
}
private String prepareHelloMessage(String... names) {
String delimiter = ""
StringBuilder sb = new StringBuilder()
for (String name : names) {
sb.append(delimiter).append(name)
delimiter = ", "
}
return this.greeting + " " + sb.toString() + "!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.setGreeting("Hi")
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
Accessing as
property
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
System.out.println(helloMessage)
}
private String prepareHelloMessage(String... names) {
String delimiter = ""
StringBuilder sb = new StringBuilder()
for (String name : names) {
sb.append(delimiter).append(name)
delimiter = ", "
}
return this.greeting + " " + sb.toString() + "!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
optional
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
System.out.println(helloMessage)
}
private String prepareHelloMessage(String... names) {
String delimiter = ""
StringBuilder sb = new StringBuilder()
for (String name : names) {
sb.append(delimiter).append(name)
delimiter = ", "
}
this.greeting + " " + sb.toString() + "!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
shortcut
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
println(helloMessage)
}
private String prepareHelloMessage(String... names) {
String delimiter = ""
StringBuilder sb = new StringBuilder()
for (String name : names) {
sb.append(delimiter).append(name)
delimiter = ", "
}
this.greeting + " " + sb.toString() + "!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
Collections
API
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
println(helloMessage)
}
private String prepareHelloMessage(String... names) {
String joinedNames = names.join(', ')
this.greeting + " " + joinedNames + "!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
String interpolation
(GString)
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
println(helloMessage)
}
private String prepareHelloMessage(String... names) {
String joinedNames = names.join(', ')
"${this.greeting} $joinedNames!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
refactor
Groovy
optional
typing
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
String helloMessage = prepareHelloMessage(names)
println(helloMessage)
}
private String prepareHelloMessage(String... names) {
"$greeting ${names.join(', ')}!"
}
static void main(String[] args) {
final Greeter greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
class Greeter {
String greeting
void sayHiTo(String... names) {
def helloMessage = prepareHelloMessage(names)
println(helloMessage)
}
private String prepareHelloMessage(String... names) {
"$greeting ${names.join(', ')}!"
}
static void main(String[] args) {
def greeter = new Greeter()
greeter.greeting = "Hi"
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
named
constructor
Groovy
optional
parentheses
optional
parentheses
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
def helloMessage = prepareHelloMessage(names)
println(helloMessage)
}
private String prepareHelloMessage(String... names) {
"$greeting ${names.join(', ')}!"
}
static void main(String[] args) {
def greeter = new Greeter(greeting: 'Hi')
greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard")
}
}
main as
script
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
def helloMessage = prepareHelloMessage(names)
println helloMessage
}
private String prepareHelloMessage(String... names) {
"$greeting ${names.join(', ')}!"
}
static void main(String[] args) {
def greeter = new Greeter(greeting: 'Hi')
greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
}
}
class Greeter {
String greeting
void sayHiTo(String... names) {
def helloMessage = prepareHelloMessage(names)
println helloMessage
}
private String prepareHelloMessage(String... names) {
"$greeting ${names.join(', ')}!"
}
}
greeter = new Greeter(greeting: 'Hi')
greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
refactor
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
println "$greeting ${names.join(', ')}!"
}
}
greeter = new Greeter(greeting: 'Hi')
greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
Let's clean
the empty
spaces
Groovy
class Greeter {
String greeting
void sayHiTo(String... names) {
println "$greeting ${names.join(', ')}!"
}
}
greeter = new Greeter(greeting: 'Hi')
greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
Groovy: Final version
Groovy: Final version
Java 32 lines of code 880 characters
Groovy 10 lines of code 221 characters
Difference 69% 75%
class Greeter {
String greeting
void sayHiTo(String... names) {
println "$greeting ${names.join(', ')}!"
}
}
greeter = new Greeter(greeting: 'Hi')
greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
Groovy: Adventure Time!
4.
Groovy
➢ Dynamic
➢ Optional static compilation
➢ Everything is an object
➢ Operator overloading
➢ + is a call to .plus()
➢ * is a call to .multiply()
➢ Native syntax for lists, maps and ranges
➢ Methods and classes are public by default
➢ All exceptions are unchecked
➢ http://groovy-lang.org/differences.html
Differences between Java and Groovy
Getters y setters
public class Person {
private String name;
private int age;
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
int getAge() {
return age;
}
void setAge(int age) {
this.age = age;
}
}
Getters y setters
class Person {
String name
int age
}
public class Person {
private String name;
private int age;
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
int getAge() {
return age;
}
void setAge(int age) {
this.age = age;
}
}
Named constructors
class Person {
String name
int age
}
def p = new Person(name: 'Iván', age: 36)
assert p.name == 'Iván'
p.age = 37
assert p.age == 37
Constructor Builder
import groovy.transform.builder.Builder
@Builder
class Person {
String name
int age
}
Person.builder()
.name('Iván')
.age(36)
.build()
Strings and GStrings
def name = 'Iván'
def age = 36
println "¡Hi ${name}, you are ${age} years old!"
def query = """
insert into people
(firstName, age)
values (${name}, ${age})
"""
new Sql(datasource).execute query
Strings and GStrings
def name = 'Iván'
def age = 36
println "¡Hi ${name}, you are ${age} years old!"
def query = """
insert into people
(firstName, age)
values (${name}, ${age})
"""
new Sql(datasource).execute query
Numbers that...
System.out.println(2.00 - 1.1);
// 0.8999999999999999
System.out.println(2.00 - 1.1);
// 0.8999999999999999
Numbers that...
System.out.println(3 / 2);
// 1
Numbers that...
System.out.println(3 / 2);
// 1
Numbers that...
BigDecimal by default!
assert 2.0 - 1.1 == 0.9
assert 3 / 2 == 1.5
Equals and ==
state != null &&
state.equals(State.COMPLETED);
state == State.COMPLETED
Equals and ==
state != null &&
state.equals(State.COMPLETED);
Lists
def list = ['a', 'b', 'c']
list << 'd' // list.add(“d”)
assert list.contains('d')
assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D']
assert list.findAll { it.startsWith 'a' }.size() == 1
def list = ['a', 'b', 'c']
list << 'd' // list.add(“d”)
assert list.contains('d')
assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D']
assert list.findAll { it.startsWith 'a' }.size() == 1
Lists
def list = ['a', 'b', 'c']
list << 'd' // list.add(“d”)
assert list.contains('d')
assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D']
Lists
Maps
def map = [name: 'Iván', age: 36]
assert map.name == 'Iván'
map.childs = ['Judith', 'Adriana']
assert map['childs'].contains('Adriana')
Maps
def map = [name: 'Iván', age: 36]
assert map.name == 'Iván'
map.childs = ['Judith', 'Adriana']
assert map['childs'].contains('Adriana')
Ranges
def range = 'a'..'z'
assert range.contains('i')
assert range.contains('z')
def exclusive = 1..<10
assert !exclusive.contains(10)
def inverse = 10..1
assert inverse[0] == 10
assert inverse[-1] == 1
def range = 'a'..'z'
assert range.contains('i')
assert range.contains('z')
def exclusive = 1..<10
assert !exclusive.contains(10)
def inverse = 10..1
assert inverse[0] == 10
assert inverse[-1] == 1
Ranges
Ranges
def range = 'a'..'z'
assert range.contains('i')
assert range.contains('z')
def exclusive = 1..<10
assert !exclusive.contains(10)
def inverse = 10..1
assert inverse[0] == 10
assert inverse[-1] == 1
Power asserts
assert (2 + 7) * 5 != (2 * 5) + (7 * 5)
(2 + 7) * 5 != (2 * 5) + (7 * 5)
| | | | | |
9 45 false 10 45 35
Power asserts
assert (2 + 7) * 5 != (2 * 5) + (7 * 5)
(2 + 7) * 5 != (2 * 5) + (7 * 5)
| | | | | |
9 45 false 10 45 35
Power asserts
def info = [
name: 'Iván', age: 36,
childs: [
[name: 'Judith', age: 8], [name: 'Adriana', age: 5]
]
]
assert info.childs.name.first() == 'Adriana'
info.childs.name.first() == 'Adriana'
| | | | |
| | | Judith false
| | | 6 differences (14% similarity)
| | | (Ju)d(-)i(th-)
| | | (A-)d(r)i(ana)
| | [Judith, Adriana]
| [[name:Judith, age:8], [name:Adriana, age:5]]
[name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana,
age:5]]]
Power asserts
def info = [
name: 'Iván', age: 36,
childs: [
[name: 'Judith', age: 8], [name: 'Adriana', age: 5]
]
]
assert info.childs.name.first() == 'Adriana'
info.childs.name.first() == 'Adriana'
| | | | |
| | | Judith false
| | | 6 differences (14% similarity)
| | | (Ju)d(-)i(th-)
| | | (A-)d(r)i(ana)
| | [Judith, Adriana]
| [[name:Judith, age:8], [name:Adriana, age:5]]
[name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana,
age:5]]]
Power asserts
def info = [
name: 'Iván', age: 36,
childs: [
[name: 'Judith', age: 8], [name: 'Adriana', age: 5]
]
]
assert info.childs.name.first() == 'Adriana'
info.childs.name.first() == 'Adriana'
| | | | |
| | | Judith false
| | | 6 differences (14% similarity)
| | | (Ju)d(-)i(th-)
| | | (A-)d(r)i(ana)
| | [Judith, Adriana]
| [[name:Judith, age:8], [name:Adriana, age:5]]
[name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana,
age:5]]]
Power asserts
def info = [
name: 'Iván', age: 36,
childs: [
[name: 'Judith', age: 8], [name: 'Adriana', age: 5]
]
]
assert info.childs.name.first() == 'Adriana'
info.childs.name.first() == 'Adriana'
| | | | |
| | | Judith false
| | | 6 differences (14% similarity)
| | | (Ju)d(-)i(th-)
| | | (A-)d(r)i(ana)
| | [Judith, Adriana]
| [[name:Judith, age:8], [name:Adriana, age:5]]
[name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana,
age:5]]]
Power asserts
def info = [
name: 'Iván', age: 36,
childs: [
[name: 'Judith', age: 8], [name: 'Adriana', age: 5]
]
]
assert info.childs.name.first() == 'Adriana'
info.childs.name.first() == 'Adriana'
| | | | |
| | | Judith false
| | | 6 differences (14% similarity)
| | | (Ju)d(-)i(th-)
| | | (A-)d(r)i(ana)
| | [Judith, Adriana]
| [[name:Judith, age:8], [name:Adriana, age:5]]
[name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana,
age:5]]]
def info = [
name: 'Iván', age: 36,
childs: [
[name: 'Judith', age: 8], [name: 'Adriana', age: 5]
]
]
assert info.childs.name.first() == 'Adriana'
info.childs.name.first() == 'Adriana'
| | | | |
| | | Judith false
| | | 6 differences (14% similarity)
| | | (Ju)d(-)i(th-)
| | | (A-)d(r)i(ana)
| | [Judith, Adriana]
| [[name:Judith, age:8], [name:Adriana, age:5]]
[name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana,
age:5]]]
Power asserts
Groovy truth
assert !( null )
assert !( "" )
assert !( '' )
assert !( [] )
assert !( [:] )
assert !( 0 )
Groovy truth
false
assert !( null )
assert !( "" )
assert !( '' )
assert !( [] )
assert !( [:] )
assert !( 0 )
Groovy truth
assert new Object()
assert "string"
assert 'string'
assert [1, 2]
assert [a: 1]
assert 1
false
assert !( null )
assert !( "" )
assert !( '' )
assert !( [] )
assert !( [:] )
assert !( 0 )
Groovy truth
assert new Object()
assert "string"
assert 'string'
assert [1, 2]
assert [a: 1]
assert 1
true
false
assert !( null )
assert !( "" )
assert !( '' )
assert !( [] )
assert !( [:] )
assert !( 0 )
Elvis
List result =
(names != null && names.size() > 0) ?
names : Collections.emptyList();
Elvis
def result = names ? names : []
List result =
(names != null && names.size() > 0) ?
names : Collections.emptyList();
Elvis
def result = names ? names : []
def result = names ?: []
List result =
(names != null && names.size() > 0) ?
names : Collections.emptyList();
Safe navigation
if (order != null) {
if (order.getCustomer() != null) {
if (order.getCustomer().getAddress() != null) {
System.out.println(order.getCustomer().getAddress());
}
}
}
Safe navigation
if (order != null) {
if (order.getCustomer() != null) {
if (order.getCustomer().getAddress() != null) {
System.out.println(order.getCustomer().getAddress());
}
}
}
println order?.customer?.address
Closures
def multiplier = { a, b -> a * b }
assert multiplier(2, 3) == 6
assert multiplier.call(2, 3) == 6
assert multiplier('=', 8) == '========'
def sumador = { ... numbers -> numbers.sum() }
assert sumador(1, 2, 3) == 6
assert sumador('a', 'b', 'c') == 'abc'
def multiplicador = { int a, int b -> a * b }
def sumador = { ... numbers -> numbers.sum() }
assert sumador(1, 2, 3) == 6
assert sumador('a', 'b', 'c') == 'abc'
def multiplier = { int a, int b -> a * b }
Closures
def multiplier = { a, b -> a * b }
assert multiplier(2, 3) == 6
assert multiplier.call(2, 3) == 6
assert multiplier('=', 8) == '========'
def adder = { ... numbers -> numbers.sum() }
assert adder(1, 2, 3) == 6
assert adder('a', 'b', 'c') == 'abc'
Closures
def multiplier = { a, b -> a * b }
assert multiplier(2, 3) == 6
assert multiplier.call(2, 3) == 6
assert multiplier('=', 8) == '========'
def multiplier = { int a, int b -> a * b }
Groovy Closures and Java 8 Lambdas
import static java.util.Arrays.asList;
public class JavaLambdas {
public static void main(String[] args) {
asList(1, 2, 3).stream()
.map(i -> i * 2)
.filter(i -> i > 3)
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}
import static java.util.Arrays.asList;
public class JavaLambdas {
public static void main(String[] args) {
asList(1, 2, 3).stream()
.map(i -> i * 2)
.filter(i -> i > 3)
.findFirst()
.orElseThrow(IllegalArgumentException::new);
}
}
[1, 2, 3].stream()
.map { i -> i * 2 }
.filter { i -> i > 3 }
.findFirst()
.orElseThrow(IllegalArgumentException.&newInstance)
Groovy Closures and Java 8 Lambdas
Json builder
{
"speaker": {
"firstName": "Iván",
"lastName": "López",
"address": {
"city": "Madrid",
"country": "España",
"zip": 12345
},
"conferences": [
"JavaCro",
"SpringOne 2GX",
"Greach"
]
}
}
import groovy.json.JsonBuilder
def builder = new JsonBuilder()
builder.
speaker {
firstName 'Iván'
lastName 'López'
address(
city: 'Madrid',
country: 'España',
zip: 12345,
)
conferences(
'T3chFest',
'Codemotion',
'Greach'
)
}
println builder.toPrettyString()
Json builder
import groovy.json.JsonBuilder
def builder = new JsonBuilder()
builder.
speaker {
firstName 'Iván'
lastName 'López'
address(
city: 'Madrid',
country: 'España',
zip: 12345,
)
conferences(
'JavaCro',
'SpringOne 2GX',
'Greach'
)
}
println builder.toPrettyString()
{
"speaker": {
"firstName": "Iván",
"lastName": "López",
"address": {
"city": "Madrid",
"country": "España",
"zip": 12345
},
"conferences": [
"JavaCro",
"SpringOne 2GX",
"Greach"
]
}
}
Parse XML and Json in Java
Json parser
wind: {
speed: 2.6,
deg: 170
},
clouds: {
all: 20
},
dt: 1460728800,
sys: {
type: 3,
id: 5456,
message: 0.0028,
country: "HR",
sunrise: 1460693949,
sunset: 1460742728
},
id: 3191518,
name: "Rovinj",
cod: 200
}
http://api.openweathermap.org/data/2.5/weather?
units=metric&q=Rovinj&appid=...
{
coord: {
lon: 13.64,
lat: 45.08
},
weather: [
{
id: 801,
main: "Clouds",
description: "few clouds",
icon: "02d"
}
],
base: "cmc stations",
main: {
temp: 19.06,
pressure: 1014,
humidity: 55,
temp_min: 18,
temp_max: 20
},
Json parser
wind: {
speed: 2.6,
deg: 170
},
clouds: {
all: 20
},
dt: 1460728800,
sys: {
type: 3,
id: 5456,
message: 0.0028,
country: "HR",
sunrise: 1460693949,
sunset: 1460742728
},
id: 3191518,
name: "Rovinj",
cod: 200
}
http://api.openweathermap.org/data/2.5/weather?
units=metric&q=Rovinj&appid=...
{
coord: {
lon: 13.64,
lat: 45.08
},
weather: [
{
id: 801,
main: "Clouds",
description: "few clouds",
icon: "02d"
}
],
base: "cmc stations",
main: {
temp: 19.06,
pressure: 1014,
humidity: 55,
temp_min: 18,
temp_max: 20
},
Json parser
import groovy.json.JsonSlurper
def url = "http://api.openweathermap.org/data/2.5/weather?
units=metric&q=Leganes&appid=...".toURL()
def response = new JsonSlurper().parse(url)
String weather = response.weather.collect { it.description }.join(', ')
String country = response.sys.country
String temp = response.main.temp
String city = response.name
println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC"
// Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC
{
weather: [
{
description: "few clouds",
}
],
main: {
temp: 19.06
},
sys: {
country: "HR",
},
name: "Rovinj",
}
Json parser
import groovy.json.JsonSlurper
def url = "http://api.openweathermap.org/data/2.5/weather?
units=metric&q=Rovinj&appid=...".toURL()
def response = new JsonSlurper().parse(url)
String weather = response.weather.collect { it.description }.join(', ')
String country = response.sys.country
String temp = response.main.temp
String city = response.name
println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC"
// Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC
{
weather: [
{
description: "few clouds",
}
],
main: {
temp: 19.06
},
sys: {
country: "HR",
},
name: "Rovinj",
}
import groovy.json.JsonSlurper
def url = "http://api.openweathermap.org/data/2.5/weather?
units=metric&q=Rovinj&appid=...".toURL()
def response = new JsonSlurper().parse(url)
String weather = response.weather.collect { it.description }.join(', ')
String country = response.sys.country
String temp = response.main.temp
String city = response.name
println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC"
// Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC
Json parser
{
weather: [
{
description: "few clouds",
}
],
main: {
temp: 19.06
},
sys: {
country: "HR",
},
name: "Rovinj",
}
Json parser
import groovy.json.JsonSlurper
def url = "http://api.openweathermap.org/data/2.5/weather?
units=metric&q=Rovinj&appid=...".toURL()
def response = new JsonSlurper().parse(url)
String weather = response.weather.collect { it.description }.join(', ')
String country = response.sys.country
String temp = response.main.temp
String city = response.name
println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC"
// Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC
{
weather: [
{
description: "few clouds",
}
],
main: {
temp: 19.06
},
sys: {
country: "HR",
},
name: "Rovinj",
}
Read text file
static String readFile(File file) throws IOException {
byte[] bytes = Files.readAllBytes(file.toPath());
return new String(bytes, "UTF-8");
}
public static void main(String[] args) {
File file = new File("foo");
try {
String content = readFile(file);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
static String readFile(File file) throws IOException {
byte[] bytes = Files.readAllBytes(file.toPath());
return new String(bytes, "UTF-8");
}
public static void main(String[] args) {
File file = new File("foo");
try {
String content = readFile(file);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
String content = new File('foo').text
Read text file
static String readFile(File file) throws IOException {
byte[] bytes = Files.readAllBytes(file.toPath());
return new String(bytes, "UTF-8");
}
public static void main(String[] args) {
File file = new File("foo.txt");
try {
String content = readFile(file);
System.out.println(content);
} catch (IOException e) {
e.printStackTrace();
}
}
String content = new File('foo').text
Read text file
Read the content of an URL
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class GetURLContent {
public static void main(String[] args) {
try {
URL url = new URL("http://www.google.com");
URLConnection conn = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
br.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class GetURLContent {
public static void main(String[] args) {
try {
URL url = new URL("http://www.google.com");
URLConnection conn = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
br.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
println 'http://www.google.com'.toURL().text
Read the content of an URL
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
public class GetURLContent {
public static void main(String[] args) {
try {
URL url = new URL("http://www.google.com");
URLConnection conn = url.openConnection();
BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = br.readLine()) != null) {
System.out.println(inputLine);
}
br.close();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
println 'http://www.google.com'.toURL().text
Read the content of an URL
➢ Groovy JDK
➢ Adds new types and methods
➢ http://www.groovy-lang.org/gdk.html
GDK
5.
I want more!
DSLs: Domain Specific Languages
def mailer = new Mailer()
mailer.setTo('admin@example.com', 'user@example.com')
mailer.setSubject('Urgent!')
mailer.setBody('Bla, bla, bla')
mailer.setHeaders(spam: 'no', important: true)
DSLs: Domain Specific Languages
def mailer = new Mailer()
mailer.setTo('admin@example.com', 'user@example.com')
mailer.setSubject('Urgent!')
mailer.setBody('Bla, bla, bla')
mailer.setHeaders(spam: 'no', important: true)
def mailer = new Mailer()
.setTo('admin@example.com', 'user@example.com')
.setSubject('Urgent!')
.setBody('Bla, bla, bla')
.setHeaders(spam: 'no', important: true)
DSLs: Domain Specific Languages
mail {
to 'admin@example.com', 'user@example.com'
subject 'Urgent!'
body 'Bla, bla, bla'
headers spam: 'no', important: true
}
class MailComposer {
void to(String... addresses) { println "to: $addresses"}
void subject(String subject) { println "subject: $subject" }
void body(String body) { println "body: $body" }
void headers(Map headers) { println "headers: $headers" }
}
void mail(@DelegatesTo(MailComposer) Closure composer) {
// Same as:
// new MailComposer().with(composer)
Closure cl = composer.clone()
cl.delegate = new MailComposer()
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
}
DSLs: Domain Specific Languages
mail {
to 'admin@example.com', 'user@example.com'
subject 'Urgent!'
body 'Bla, bla, bla'
headers spam: 'no', important: true
}
class MailComposer {
void to(String... addresses) { println "to: $addresses"}
void subject(String subject) { println "subject: $subject" }
void body(String body) { println "body: $body" }
void headers(Map headers) { println "headers: $headers" }
}
void mail(@DelegatesTo(MailComposer) Closure composer) {
// Same as:
// new MailComposer().with(composer)
Closure cl = composer.clone()
cl.delegate = new MailComposer()
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
}
DSLs: Domain Specific Languages
mail {
to 'admin@example.com', 'user@example.com'
subject 'Urgent!'
body 'Bla, bla, bla'
headers spam: 'no', important: true
}
class MailComposer {
void to(String... addresses) { println "to: $addresses"}
void subject(String subject) { println "subject: $subject" }
void body(String body) { println "body: $body" }
void headers(Map headers) { println "headers: $headers" }
}
void mail(@DelegatesTo(MailComposer) Closure composer) {
// Same as:
// new MailComposer().with(composer)
Closure cl = composer.clone()
cl.delegate = new MailComposer()
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
}
➢ +50 transformations out-of-the-box
➢ @ToString, @EqualsAndHashCode, @InheritConstructors,
@Sortable, @Delegate, @Immutable, @CompileStatic,...
AST Transformations
@EqualsAndHashCode
public class User extends java.lang.Object {
private String name
private Integer age
public int hashCode() {
java.lang.Object _result = org.codehaus.groovy.util.HashCodeHelper.initHash()
if (!(this.getName().is(this))) {
_result = HashCodeHelper.updateHash(_result, this.getName())
}
if (!(this.getAge().is(this))) {
_result = HashCodeHelper.updateHash(_result, this.getAge())
}
return _result
}
public boolean canEqual(Object other) {
return other instanceof User
}
public boolean equals(Object other) {
if ( other == null) {
return false
}
if (this.is(other)) {
return true
}
if (!( other instanceof User)) {
return false
}
User otherTyped = (( other ) as User)
if (!(otherTyped.canEqual( this ))) {
return false
}
if (!(this.getName() == otherTyped.getName())) {
return false
}
if (!(this.getAge() == otherTyped.getAge())) {
return false
}
return true
}
}
@EqualsAndHashCode
@groovy.transform.EqualsAndHashCode
class User {
String name
Integer age
}
JavaCro 2016 - From Java to Groovy: Adventure Time!
Thank you!
Questions?
@ilopmar
lopez.ivan@gmail.com
https://github.com/ilopmar
Iván López
http://bit.ly/javacro-groovy

More Related Content

PDF
An Introduction to Groovy for Java Developers
ODP
Groovy and Grails intro
PPT
Groovy for Java Developers
PDF
Groovy for java developers
KEY
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
PPT
Eclipsecon08 Introduction To Groovy
PDF
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
PDF
Groovy Up Your Code
An Introduction to Groovy for Java Developers
Groovy and Grails intro
Groovy for Java Developers
Groovy for java developers
Groovy overview, DSLs and ecosystem - Mars JUG - 2010
Eclipsecon08 Introduction To Groovy
GR8Conf 2009: Practical Groovy DSL by Guillaume Laforge
Groovy Up Your Code

What's hot (20)

PPTX
Golang workshop - Mindbowser
PDF
A Recovering Java Developer Learns to Go
PDF
Understanding how concurrency work in os
PDF
Dsl로 만나는 groovy
PDF
Golang
PDF
Ruby Presentation
PDF
Let's Play Dart
PDF
FTD JVM Internals
PDF
Writing Fast Code (JP) - PyCon JP 2015
PPTX
Dart the Better JavaScript
PDF
Ruby Programming Introduction
PDF
Dart, Darrt, Darrrt
PDF
Structured web programming
PDF
Introduction to Google's Go programming language
PPTX
PPTX
TypeScript - Silver Bullet for the Full-stack Developers
PDF
Groovy Finesse
PDF
Introduction to Ruby
Golang workshop - Mindbowser
A Recovering Java Developer Learns to Go
Understanding how concurrency work in os
Dsl로 만나는 groovy
Golang
Ruby Presentation
Let's Play Dart
FTD JVM Internals
Writing Fast Code (JP) - PyCon JP 2015
Dart the Better JavaScript
Ruby Programming Introduction
Dart, Darrt, Darrrt
Structured web programming
Introduction to Google's Go programming language
TypeScript - Silver Bullet for the Full-stack Developers
Groovy Finesse
Introduction to Ruby
Ad

Viewers also liked (20)

PPTX
Confessions of a java developer that fell in love with the groovy language
PDF
Groovy Powered Clean Code
PDF
Metaprogramming with Groovy
PDF
RCDC_Evans_Ave - Sheet - A101 - LIGHTING PLAN
PDF
Alfresco tech talk live share extensibility metadata and actions for 4.1
PDF
Mapping Human-Centric Product Vision (ProductCamp Boston 2016)
PPTX
2014 Qoppa Software PDF Solutions
PPTX
Power of LinkedIn Lookup: finding hidden talent in your organization | Talent...
PPTX
Brooklyn college names business school in honor of alumnus
PPTX
Loan Point- A Reliable Hub of Money Lending
PPTX
Mkt content Mercado
PPT
21 1402262356 15_15_omn
PDF
Chemistry Connect
PPT
тру
PDF
SparkLabs Global Wireless Industry Overview 2014
PDF
DASH - Josh Curtis - Dominating Influencer Marketing for Mobile Games - Chart...
PDF
Analisis arquitectonico y estudio de medio geografico del sitio arqueologico ...
PPTX
Bianco toro
PPTX
презентация Microsoft office power point
PPTX
Business Administration Studies at Brooklyn College
Confessions of a java developer that fell in love with the groovy language
Groovy Powered Clean Code
Metaprogramming with Groovy
RCDC_Evans_Ave - Sheet - A101 - LIGHTING PLAN
Alfresco tech talk live share extensibility metadata and actions for 4.1
Mapping Human-Centric Product Vision (ProductCamp Boston 2016)
2014 Qoppa Software PDF Solutions
Power of LinkedIn Lookup: finding hidden talent in your organization | Talent...
Brooklyn college names business school in honor of alumnus
Loan Point- A Reliable Hub of Money Lending
Mkt content Mercado
21 1402262356 15_15_omn
Chemistry Connect
тру
SparkLabs Global Wireless Industry Overview 2014
DASH - Josh Curtis - Dominating Influencer Marketing for Mobile Games - Chart...
Analisis arquitectonico y estudio de medio geografico del sitio arqueologico ...
Bianco toro
презентация Microsoft office power point
Business Administration Studies at Brooklyn College
Ad

Similar to JavaCro 2016 - From Java to Groovy: Adventure Time! (20)

PDF
Apache Groovy: the language and the ecosystem
PDF
Introduction to Oracle Groovy
PPTX
Groovy Programming Language
ZIP
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
PDF
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
PDF
OpenLogic
ODP
PDF
Groovy And Grails JUG Trento
PDF
Groovy a Scripting Language for Java
PDF
Groovy And Grails JUG Padova
PDF
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
PDF
Whats New In Groovy 1.6?
PPT
Groovy presentation
PPT
Groovy introduction
PDF
Groovy Online 100
PDF
Groovy And Grails JUG Sardegna
PPTX
Groovy!
PDF
Infinum android talks_10_getting groovy on android
PDF
Oscon Java Testing on the Fast Lane
PDF
Java Edge.2009.Grails.Web.Dev.Made.Easy
Apache Groovy: the language and the ecosystem
Introduction to Oracle Groovy
Groovy Programming Language
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
OpenLogic
Groovy And Grails JUG Trento
Groovy a Scripting Language for Java
Groovy And Grails JUG Padova
GR8Conf 2009: What's New in Groovy 1.6? by Guillaume Laforge
Whats New In Groovy 1.6?
Groovy presentation
Groovy introduction
Groovy Online 100
Groovy And Grails JUG Sardegna
Groovy!
Infinum android talks_10_getting groovy on android
Oscon Java Testing on the Fast Lane
Java Edge.2009.Grails.Web.Dev.Made.Easy

More from Iván López Martín (20)

PDF
CommitConf 2025 - Spring AI: IA Avanzada para desarrolladores Spring
PDF
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
PDF
CommitConf 2024 - Spring Boot <3 Testcontainers
PDF
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
PDF
VMware - Testcontainers y Spring Boot
PDF
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
PDF
Codemotion Madrid 2023 - Testcontainers y Spring Boot
PDF
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
PDF
Construyendo un API REST con Spring Boot y GraalVM
PDF
jLove 2020 - Micronaut and graalvm: The power of AoT
PDF
Codemotion Madrid 2020 - Serverless con Micronaut
PDF
JConf Perú 2020 - ¡Micronaut en acción!
PDF
JConf Perú 2020 - Micronaut + GraalVM = <3
PDF
JConf México 2020 - Micronaut + GraalVM = <3
PDF
Developing Micronaut Applications With IntelliJ IDEA
PDF
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
PDF
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
PDF
Greach 2019 - Creating Micronaut Configurations
PDF
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
PDF
JavaDay Lviv 2019 - Micronaut in action!
CommitConf 2025 - Spring AI: IA Avanzada para desarrolladores Spring
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 Testcontainers
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
VMware - Testcontainers y Spring Boot
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
Codemotion Madrid 2023 - Testcontainers y Spring Boot
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
Construyendo un API REST con Spring Boot y GraalVM
jLove 2020 - Micronaut and graalvm: The power of AoT
Codemotion Madrid 2020 - Serverless con Micronaut
JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3
Developing Micronaut Applications With IntelliJ IDEA
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Greach 2019 - Creating Micronaut Configurations
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
JavaDay Lviv 2019 - Micronaut in action!

Recently uploaded (20)

PDF
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PDF
Encapsulation theory and applications.pdf
PPTX
Big Data Technologies - Introduction.pptx
PDF
NewMind AI Monthly Chronicles - July 2025
PDF
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Empathic Computing: Creating Shared Understanding
PPTX
MYSQL Presentation for SQL database connectivity
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
CIFDAQ's Market Insight: SEC Turns Pro Crypto
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Spectral efficient network and resource selection model in 5G networks
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
Bridging biosciences and deep learning for revolutionary discoveries: a compr...
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
Review of recent advances in non-invasive hemoglobin estimation
Building Integrated photovoltaic BIPV_UPV.pdf
Mobile App Security Testing_ A Comprehensive Guide.pdf
Encapsulation theory and applications.pdf
Big Data Technologies - Introduction.pptx
NewMind AI Monthly Chronicles - July 2025
Shreyas Phanse Resume: Experienced Backend Engineer | Java • Spring Boot • Ka...
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
The AUB Centre for AI in Media Proposal.docx
Empathic Computing: Creating Shared Understanding
MYSQL Presentation for SQL database connectivity
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
CIFDAQ's Market Insight: SEC Turns Pro Crypto
Digital-Transformation-Roadmap-for-Companies.pptx
Spectral efficient network and resource selection model in 5G networks
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Encapsulation_ Review paper, used for researhc scholars
Dropbox Q2 2025 Financial Results & Investor Presentation

JavaCro 2016 - From Java to Groovy: Adventure Time!

  • 1. From Java to Groovy: Adventure Time! Iván López @ilopmar
  • 2. ➢ Iván López @ilopmar ➢ Groovy & Grails developer ➢ @MadridGUG coordinator ➢ Greach organizer @greachconf http://greachconf.com ➢ Speaker: SpringOne 2GX, GR8Conf, GGX, Codemotion, GeeCon, jDays, Spring IO, Greach, ConFoo, ConFess, RigaDevDays... About me...
  • 4. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 5. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 6. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 7. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 8. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 9. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 10. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 11. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 12. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 13. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  • 16. ➢ Java is solid ➢ Known by a lot of developers ➢ Used everywhere ➢ Is fast But... ➢ Java is verbose ➢ Can be annoying ➢ It's not dynamic Why not Java?
  • 18. Greeter.java public class Greeter { private String greeting; public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names); System.out.println(helloMessage); } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } private String prepareHelloMessage(String... names) { String delimiter = ""; StringBuilder sb = new StringBuilder(); for (String name : names) { sb.append(delimiter).append(name); delimiter = ", "; } return this.greeting + " " + sb.toString() + "!"; } public static void main(String[] args) { final Greeter greeter = new Greeter(); greeter.setGreeting("Hi"); greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard"); } } Rename
  • 19. public class Greeter { private String greeting; public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names); System.out.println(helloMessage); } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } private String prepareHelloMessage(String... names) { String delimiter = ""; StringBuilder sb = new StringBuilder(); for (String name : names) { sb.append(delimiter).append(name); delimiter = ", "; } return this.greeting + " " + sb.toString() + "!"; } public static void main(String[] args) { final Greeter greeter = new Greeter(); greeter.setGreeting("Hi"); greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard"); } } Greeter.groovy
  • 20. Groovy public class Greeter { private String greeting; public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names); System.out.println(helloMessage); } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } private String prepareHelloMessage(String... names) { String delimiter = ""; StringBuilder sb = new StringBuilder(); for (String name : names) { sb.append(delimiter).append(name); delimiter = ", "; } return this.greeting + " " + sb.toString() + "!"; } public static void main(String[] args) { final Greeter greeter = new Greeter(); greeter.setGreeting("Hi"); greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard"); } }
  • 21. optional public class Greeter { private String greeting public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } public String getGreeting() { return greeting } public void setGreeting(String greeting) { this.greeting = greeting } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } public static void main(String[] args) { final Greeter greeter = new Greeter() greeter.setGreeting("Hi") greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } optional Groovy
  • 22. verbose getter/setter Groovy class Greeter { private String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } String getGreeting() { return greeting } void setGreeting(String greeting) { this.greeting = greeting } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.setGreeting("Hi") greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } }
  • 23. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.setGreeting("Hi") greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } Accessing as property Groovy
  • 24. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } optional Groovy
  • 25. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } shortcut Groovy
  • 26. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } Collections API Groovy
  • 27. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { String joinedNames = names.join(', ') this.greeting + " " + joinedNames + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } String interpolation (GString) Groovy
  • 28. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { String joinedNames = names.join(', ') "${this.greeting} $joinedNames!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } refactor Groovy
  • 29. optional typing Groovy class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } }
  • 30. class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { def greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } named constructor Groovy
  • 31. optional parentheses optional parentheses Groovy class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { def greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } }
  • 32. main as script Groovy class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println helloMessage } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { def greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" } }
  • 33. class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println helloMessage } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" refactor Groovy
  • 34. class Greeter { String greeting void sayHiTo(String... names) { println "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" Let's clean the empty spaces Groovy
  • 35. class Greeter { String greeting void sayHiTo(String... names) { println "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" Groovy: Final version
  • 36. Groovy: Final version Java 32 lines of code 880 characters Groovy 10 lines of code 221 characters Difference 69% 75% class Greeter { String greeting void sayHiTo(String... names) { println "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
  • 39. ➢ Dynamic ➢ Optional static compilation ➢ Everything is an object ➢ Operator overloading ➢ + is a call to .plus() ➢ * is a call to .multiply() ➢ Native syntax for lists, maps and ranges ➢ Methods and classes are public by default ➢ All exceptions are unchecked ➢ http://groovy-lang.org/differences.html Differences between Java and Groovy
  • 40. Getters y setters public class Person { private String name; private int age; String getName() { return name; } void setName(String name) { this.name = name; } int getAge() { return age; } void setAge(int age) { this.age = age; } }
  • 41. Getters y setters class Person { String name int age } public class Person { private String name; private int age; String getName() { return name; } void setName(String name) { this.name = name; } int getAge() { return age; } void setAge(int age) { this.age = age; } }
  • 42. Named constructors class Person { String name int age } def p = new Person(name: 'Iván', age: 36) assert p.name == 'Iván' p.age = 37 assert p.age == 37
  • 43. Constructor Builder import groovy.transform.builder.Builder @Builder class Person { String name int age } Person.builder() .name('Iván') .age(36) .build()
  • 44. Strings and GStrings def name = 'Iván' def age = 36 println "¡Hi ${name}, you are ${age} years old!" def query = """ insert into people (firstName, age) values (${name}, ${age}) """ new Sql(datasource).execute query
  • 45. Strings and GStrings def name = 'Iván' def age = 36 println "¡Hi ${name}, you are ${age} years old!" def query = """ insert into people (firstName, age) values (${name}, ${age}) """ new Sql(datasource).execute query
  • 46. Numbers that... System.out.println(2.00 - 1.1); // 0.8999999999999999
  • 47. System.out.println(2.00 - 1.1); // 0.8999999999999999 Numbers that...
  • 48. System.out.println(3 / 2); // 1 Numbers that...
  • 49. System.out.println(3 / 2); // 1 Numbers that...
  • 50. BigDecimal by default! assert 2.0 - 1.1 == 0.9 assert 3 / 2 == 1.5
  • 51. Equals and == state != null && state.equals(State.COMPLETED);
  • 52. state == State.COMPLETED Equals and == state != null && state.equals(State.COMPLETED);
  • 53. Lists def list = ['a', 'b', 'c'] list << 'd' // list.add(“d”) assert list.contains('d') assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D'] assert list.findAll { it.startsWith 'a' }.size() == 1
  • 54. def list = ['a', 'b', 'c'] list << 'd' // list.add(“d”) assert list.contains('d') assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D'] assert list.findAll { it.startsWith 'a' }.size() == 1 Lists
  • 55. def list = ['a', 'b', 'c'] list << 'd' // list.add(“d”) assert list.contains('d') assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D'] Lists
  • 56. Maps def map = [name: 'Iván', age: 36] assert map.name == 'Iván' map.childs = ['Judith', 'Adriana'] assert map['childs'].contains('Adriana')
  • 57. Maps def map = [name: 'Iván', age: 36] assert map.name == 'Iván' map.childs = ['Judith', 'Adriana'] assert map['childs'].contains('Adriana')
  • 58. Ranges def range = 'a'..'z' assert range.contains('i') assert range.contains('z') def exclusive = 1..<10 assert !exclusive.contains(10) def inverse = 10..1 assert inverse[0] == 10 assert inverse[-1] == 1
  • 59. def range = 'a'..'z' assert range.contains('i') assert range.contains('z') def exclusive = 1..<10 assert !exclusive.contains(10) def inverse = 10..1 assert inverse[0] == 10 assert inverse[-1] == 1 Ranges
  • 60. Ranges def range = 'a'..'z' assert range.contains('i') assert range.contains('z') def exclusive = 1..<10 assert !exclusive.contains(10) def inverse = 10..1 assert inverse[0] == 10 assert inverse[-1] == 1
  • 61. Power asserts assert (2 + 7) * 5 != (2 * 5) + (7 * 5) (2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35
  • 62. Power asserts assert (2 + 7) * 5 != (2 * 5) + (7 * 5) (2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35
  • 63. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  • 64. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  • 65. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  • 66. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  • 67. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  • 68. def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]] Power asserts
  • 69. Groovy truth assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  • 70. Groovy truth false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  • 71. Groovy truth assert new Object() assert "string" assert 'string' assert [1, 2] assert [a: 1] assert 1 false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  • 72. Groovy truth assert new Object() assert "string" assert 'string' assert [1, 2] assert [a: 1] assert 1 true false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  • 73. Elvis List result = (names != null && names.size() > 0) ? names : Collections.emptyList();
  • 74. Elvis def result = names ? names : [] List result = (names != null && names.size() > 0) ? names : Collections.emptyList();
  • 75. Elvis def result = names ? names : [] def result = names ?: [] List result = (names != null && names.size() > 0) ? names : Collections.emptyList();
  • 76. Safe navigation if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } }
  • 77. Safe navigation if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } } println order?.customer?.address
  • 78. Closures def multiplier = { a, b -> a * b } assert multiplier(2, 3) == 6 assert multiplier.call(2, 3) == 6 assert multiplier('=', 8) == '========' def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplicador = { int a, int b -> a * b }
  • 79. def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplier = { int a, int b -> a * b } Closures def multiplier = { a, b -> a * b } assert multiplier(2, 3) == 6 assert multiplier.call(2, 3) == 6 assert multiplier('=', 8) == '========'
  • 80. def adder = { ... numbers -> numbers.sum() } assert adder(1, 2, 3) == 6 assert adder('a', 'b', 'c') == 'abc' Closures def multiplier = { a, b -> a * b } assert multiplier(2, 3) == 6 assert multiplier.call(2, 3) == 6 assert multiplier('=', 8) == '========' def multiplier = { int a, int b -> a * b }
  • 81. Groovy Closures and Java 8 Lambdas import static java.util.Arrays.asList; public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); } }
  • 82. import static java.util.Arrays.asList; public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); } } [1, 2, 3].stream() .map { i -> i * 2 } .filter { i -> i > 3 } .findFirst() .orElseThrow(IllegalArgumentException.&newInstance) Groovy Closures and Java 8 Lambdas
  • 83. Json builder { "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "JavaCro", "SpringOne 2GX", "Greach" ] } } import groovy.json.JsonBuilder def builder = new JsonBuilder() builder. speaker { firstName 'Iván' lastName 'López' address( city: 'Madrid', country: 'España', zip: 12345, ) conferences( 'T3chFest', 'Codemotion', 'Greach' ) } println builder.toPrettyString()
  • 84. Json builder import groovy.json.JsonBuilder def builder = new JsonBuilder() builder. speaker { firstName 'Iván' lastName 'López' address( city: 'Madrid', country: 'España', zip: 12345, ) conferences( 'JavaCro', 'SpringOne 2GX', 'Greach' ) } println builder.toPrettyString() { "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "JavaCro", "SpringOne 2GX", "Greach" ] } }
  • 85. Parse XML and Json in Java
  • 86. Json parser wind: { speed: 2.6, deg: 170 }, clouds: { all: 20 }, dt: 1460728800, sys: { type: 3, id: 5456, message: 0.0028, country: "HR", sunrise: 1460693949, sunset: 1460742728 }, id: 3191518, name: "Rovinj", cod: 200 } http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=... { coord: { lon: 13.64, lat: 45.08 }, weather: [ { id: 801, main: "Clouds", description: "few clouds", icon: "02d" } ], base: "cmc stations", main: { temp: 19.06, pressure: 1014, humidity: 55, temp_min: 18, temp_max: 20 },
  • 87. Json parser wind: { speed: 2.6, deg: 170 }, clouds: { all: 20 }, dt: 1460728800, sys: { type: 3, id: 5456, message: 0.0028, country: "HR", sunrise: 1460693949, sunset: 1460742728 }, id: 3191518, name: "Rovinj", cod: 200 } http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=... { coord: { lon: 13.64, lat: 45.08 }, weather: [ { id: 801, main: "Clouds", description: "few clouds", icon: "02d" } ], base: "cmc stations", main: { temp: 19.06, pressure: 1014, humidity: 55, temp_min: 18, temp_max: 20 },
  • 88. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Leganes&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  • 89. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  • 90. import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC Json parser { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  • 91. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  • 92. Read text file static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8"); } public static void main(String[] args) { File file = new File("foo"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); } }
  • 93. static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8"); } public static void main(String[] args) { File file = new File("foo"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); } } String content = new File('foo').text Read text file
  • 94. static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8"); } public static void main(String[] args) { File file = new File("foo.txt"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); } } String content = new File('foo').text Read text file
  • 95. Read the content of an URL import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
  • 96. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } println 'http://www.google.com'.toURL().text Read the content of an URL
  • 97. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } println 'http://www.google.com'.toURL().text Read the content of an URL
  • 98. ➢ Groovy JDK ➢ Adds new types and methods ➢ http://www.groovy-lang.org/gdk.html GDK
  • 100. DSLs: Domain Specific Languages def mailer = new Mailer() mailer.setTo('admin@example.com', 'user@example.com') mailer.setSubject('Urgent!') mailer.setBody('Bla, bla, bla') mailer.setHeaders(spam: 'no', important: true)
  • 101. DSLs: Domain Specific Languages def mailer = new Mailer() mailer.setTo('admin@example.com', 'user@example.com') mailer.setSubject('Urgent!') mailer.setBody('Bla, bla, bla') mailer.setHeaders(spam: 'no', important: true) def mailer = new Mailer() .setTo('admin@example.com', 'user@example.com') .setSubject('Urgent!') .setBody('Bla, bla, bla') .setHeaders(spam: 'no', important: true)
  • 102. DSLs: Domain Specific Languages mail { to 'admin@example.com', 'user@example.com' subject 'Urgent!' body 'Bla, bla, bla' headers spam: 'no', important: true } class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" } } void mail(@DelegatesTo(MailComposer) Closure composer) { // Same as: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl() }
  • 103. DSLs: Domain Specific Languages mail { to 'admin@example.com', 'user@example.com' subject 'Urgent!' body 'Bla, bla, bla' headers spam: 'no', important: true } class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" } } void mail(@DelegatesTo(MailComposer) Closure composer) { // Same as: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl() }
  • 104. DSLs: Domain Specific Languages mail { to 'admin@example.com', 'user@example.com' subject 'Urgent!' body 'Bla, bla, bla' headers spam: 'no', important: true } class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" } } void mail(@DelegatesTo(MailComposer) Closure composer) { // Same as: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl() }
  • 105. ➢ +50 transformations out-of-the-box ➢ @ToString, @EqualsAndHashCode, @InheritConstructors, @Sortable, @Delegate, @Immutable, @CompileStatic,... AST Transformations
  • 106. @EqualsAndHashCode public class User extends java.lang.Object { private String name private Integer age public int hashCode() { java.lang.Object _result = org.codehaus.groovy.util.HashCodeHelper.initHash() if (!(this.getName().is(this))) { _result = HashCodeHelper.updateHash(_result, this.getName()) } if (!(this.getAge().is(this))) { _result = HashCodeHelper.updateHash(_result, this.getAge()) } return _result } public boolean canEqual(Object other) { return other instanceof User } public boolean equals(Object other) { if ( other == null) { return false } if (this.is(other)) { return true } if (!( other instanceof User)) { return false } User otherTyped = (( other ) as User) if (!(otherTyped.canEqual( this ))) { return false } if (!(this.getName() == otherTyped.getName())) { return false } if (!(this.getAge() == otherTyped.getAge())) { return false } return true } }