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
}
Thank you!
Questions?
@ilopmar
lopez.ivan@gmail.com
https://github.com/ilopmar
Iván López
http://bit.ly/javacro-groovy

More Related Content

What's hot

Golang workshop - Mindbowser
Golang workshop - MindbowserGolang workshop - Mindbowser
Golang workshop - MindbowserMindbowser Inc
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoMatt Stine
 
Understanding how concurrency work in os
Understanding how concurrency work in osUnderstanding how concurrency work in os
Understanding how concurrency work in osGenchiLu1
 
Dsl로 만나는 groovy
Dsl로 만나는 groovyDsl로 만나는 groovy
Dsl로 만나는 groovySeeyoung Chang
 
Ruby Presentation
Ruby Presentation Ruby Presentation
Ruby Presentation platico_dev
 
Writing Fast Code (JP) - PyCon JP 2015
Writing Fast Code (JP) - PyCon JP 2015Writing Fast Code (JP) - PyCon JP 2015
Writing Fast Code (JP) - PyCon JP 2015Younggun Kim
 
Dart the Better JavaScript
Dart the Better JavaScriptDart the Better JavaScript
Dart the Better JavaScriptJorg Janke
 
Ruby Programming Introduction
Ruby Programming IntroductionRuby Programming Introduction
Ruby Programming IntroductionAnthony Brown
 
Dart, Darrt, Darrrt
Dart, Darrt, DarrrtDart, Darrt, Darrrt
Dart, Darrt, DarrrtJana Moudrá
 
Structured web programming
Structured web programmingStructured web programming
Structured web programmingahfast
 
Introduction to Google's Go programming language
Introduction to Google's Go programming languageIntroduction to Google's Go programming language
Introduction to Google's Go programming languageMario Castro Contreras
 
TypeScript - Silver Bullet for the Full-stack Developers
TypeScript - Silver Bullet for the Full-stack DevelopersTypeScript - Silver Bullet for the Full-stack Developers
TypeScript - Silver Bullet for the Full-stack DevelopersRutenis Turcinas
 
Groovy Finesse
Groovy FinesseGroovy Finesse
Groovy Finessemzgubin
 
Introduction to Ruby
Introduction to RubyIntroduction to Ruby
Introduction to Rubykim.mens
 

What's hot (20)

Golang workshop - Mindbowser
Golang workshop - MindbowserGolang workshop - Mindbowser
Golang workshop - Mindbowser
 
Dart
DartDart
Dart
 
A Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to GoA Recovering Java Developer Learns to Go
A Recovering Java Developer Learns to Go
 
Understanding how concurrency work in os
Understanding how concurrency work in osUnderstanding how concurrency work in os
Understanding how concurrency work in os
 
Dsl로 만나는 groovy
Dsl로 만나는 groovyDsl로 만나는 groovy
Dsl로 만나는 groovy
 
Golang
GolangGolang
Golang
 
Ruby Presentation
Ruby Presentation Ruby Presentation
Ruby Presentation
 
Let's Play Dart
Let's Play DartLet's Play Dart
Let's Play Dart
 
Golang
GolangGolang
Golang
 
FTD JVM Internals
FTD JVM InternalsFTD JVM Internals
FTD JVM Internals
 
Writing Fast Code (JP) - PyCon JP 2015
Writing Fast Code (JP) - PyCon JP 2015Writing Fast Code (JP) - PyCon JP 2015
Writing Fast Code (JP) - PyCon JP 2015
 
Dart the Better JavaScript
Dart the Better JavaScriptDart the Better JavaScript
Dart the Better JavaScript
 
Ruby Programming Introduction
Ruby Programming IntroductionRuby Programming Introduction
Ruby Programming Introduction
 
Dart, Darrt, Darrrt
Dart, Darrt, DarrrtDart, Darrt, Darrrt
Dart, Darrt, Darrrt
 
Structured web programming
Structured web programmingStructured web programming
Structured web programming
 
Introduction to Google's Go programming language
Introduction to Google's Go programming languageIntroduction to Google's Go programming language
Introduction to Google's Go programming language
 
Go Lang
Go LangGo Lang
Go Lang
 
TypeScript - Silver Bullet for the Full-stack Developers
TypeScript - Silver Bullet for the Full-stack DevelopersTypeScript - Silver Bullet for the Full-stack Developers
TypeScript - Silver Bullet for the Full-stack Developers
 
Groovy Finesse
Groovy FinesseGroovy Finesse
Groovy Finesse
 
Introduction to Ruby
Introduction to RubyIntroduction to Ruby
Introduction to Ruby
 

Viewers also liked

Confessions of a java developer that fell in love with the groovy language
Confessions of a java developer that fell in love with the groovy languageConfessions of a java developer that fell in love with the groovy language
Confessions of a java developer that fell in love with the groovy languageVictor Trakhtenberg
 
Groovy Powered Clean Code
Groovy Powered Clean CodeGroovy Powered Clean Code
Groovy Powered Clean CodeGR8Conf
 
Metaprogramming with Groovy
Metaprogramming with GroovyMetaprogramming with Groovy
Metaprogramming with GroovyGR8Conf
 
RCDC_Evans_Ave - Sheet - A101 - LIGHTING PLAN
RCDC_Evans_Ave - Sheet - A101 - LIGHTING PLANRCDC_Evans_Ave - Sheet - A101 - LIGHTING PLAN
RCDC_Evans_Ave - Sheet - A101 - LIGHTING PLANDalton Goodwin
 
Alfresco tech talk live share extensibility metadata and actions for 4.1
Alfresco tech talk live share extensibility metadata and actions for 4.1Alfresco tech talk live share extensibility metadata and actions for 4.1
Alfresco tech talk live share extensibility metadata and actions for 4.1Alfresco Software
 
Mapping Human-Centric Product Vision (ProductCamp Boston 2016)
Mapping Human-Centric Product Vision (ProductCamp Boston 2016)Mapping Human-Centric Product Vision (ProductCamp Boston 2016)
Mapping Human-Centric Product Vision (ProductCamp Boston 2016)ProductCamp Boston
 
2014 Qoppa Software PDF Solutions
2014 Qoppa Software PDF Solutions 2014 Qoppa Software PDF Solutions
2014 Qoppa Software PDF Solutions Susan Sims
 
Power of LinkedIn Lookup: finding hidden talent in your organization | Talent...
Power of LinkedIn Lookup: finding hidden talent in your organization | Talent...Power of LinkedIn Lookup: finding hidden talent in your organization | Talent...
Power of LinkedIn Lookup: finding hidden talent in your organization | Talent...LinkedIn Talent Solutions
 
Brooklyn college names business school in honor of alumnus
Brooklyn college names business school in honor of alumnus Brooklyn college names business school in honor of alumnus
Brooklyn college names business school in honor of alumnus Craig Raucher New York
 
Loan Point- A Reliable Hub of Money Lending
Loan Point- A Reliable Hub of Money LendingLoan Point- A Reliable Hub of Money Lending
Loan Point- A Reliable Hub of Money LendingJessica Rodz
 
21 1402262356 15_15_omn
21 1402262356 15_15_omn21 1402262356 15_15_omn
21 1402262356 15_15_omnmtc124
 
тру
трутру
труmtc124
 
SparkLabs Global Wireless Industry Overview 2014
SparkLabs Global Wireless Industry Overview 2014SparkLabs Global Wireless Industry Overview 2014
SparkLabs Global Wireless Industry Overview 2014Bernard Moon
 
DASH - Josh Curtis - Dominating Influencer Marketing for Mobile Games - Chart...
DASH - Josh Curtis - Dominating Influencer Marketing for Mobile Games - Chart...DASH - Josh Curtis - Dominating Influencer Marketing for Mobile Games - Chart...
DASH - Josh Curtis - Dominating Influencer Marketing for Mobile Games - Chart...Josh Curtis
 
Analisis arquitectonico y estudio de medio geografico del sitio arqueologico ...
Analisis arquitectonico y estudio de medio geografico del sitio arqueologico ...Analisis arquitectonico y estudio de medio geografico del sitio arqueologico ...
Analisis arquitectonico y estudio de medio geografico del sitio arqueologico ...Cristyuli Yamille Celis Gómez
 
презентация Microsoft office power point
презентация Microsoft office power pointпрезентация Microsoft office power point
презентация Microsoft office power pointmtc124
 
Business Administration Studies at Brooklyn College
Business Administration Studies at Brooklyn College Business Administration Studies at Brooklyn College
Business Administration Studies at Brooklyn College Craig Raucher New York
 

Viewers also liked (20)

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

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

Building domain-specific languages with Groovy
Building domain-specific languages with GroovyBuilding domain-specific languages with Groovy
Building domain-specific languages with GroovyYaroslav Yermilov
 
Venkat Subramaniam Blending Java With Dynamic Languages
Venkat Subramaniam Blending Java With Dynamic LanguagesVenkat Subramaniam Blending Java With Dynamic Languages
Venkat Subramaniam Blending Java With Dynamic Languagesdeimos
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGuillaume Laforge
 
Groovy Finesse
Groovy FinesseGroovy Finesse
Groovy Finessemzgubin
 
Dynamic Languages on the JVM
Dynamic Languages on the JVMDynamic Languages on the JVM
Dynamic Languages on the JVMelliando dias
 
Why don't you Groovy?
Why don't you Groovy?Why don't you Groovy?
Why don't you Groovy?Orest Ivasiv
 
Groovy a Scripting Language for Java
Groovy a Scripting Language for JavaGroovy a Scripting Language for Java
Groovy a Scripting Language for JavaCharles Anderson
 
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume LaforgeGroovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume LaforgeGuillaume Laforge
 
Groovy introduction
Groovy introductionGroovy introduction
Groovy introductiongpottepalem
 
Step by Step Guide on Essay Format in APA For Beginners
Step by Step Guide on Essay Format in APA For BeginnersStep by Step Guide on Essay Format in APA For Beginners
Step by Step Guide on Essay Format in APA For Beginnerscalltutors
 
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPCBuild Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPCTim Burks
 
Introduction to Java Programming.pdf
Introduction to Java Programming.pdfIntroduction to Java Programming.pdf
Introduction to Java Programming.pdfAdiseshaK
 
OSGi enRoute Unveiled - P Kriens
OSGi enRoute Unveiled - P KriensOSGi enRoute Unveiled - P Kriens
OSGi enRoute Unveiled - P Kriensmfrancis
 
JRuby in a Java World
JRuby in a Java WorldJRuby in a Java World
JRuby in a Java WorldMark Menard
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James NelsonGWTcon
 
NodeJS vs Golang - A detailed comparison
NodeJS vs Golang - A detailed comparisonNodeJS vs Golang - A detailed comparison
NodeJS vs Golang - A detailed comparisonDevathon
 
Everything-as-code. A polyglot journey.
Everything-as-code. A polyglot journey.Everything-as-code. A polyglot journey.
Everything-as-code. A polyglot journey.Mario-Leander Reimer
 
Everything-as-code - a polyglot journey.
Everything-as-code - a polyglot journey.Everything-as-code - a polyglot journey.
Everything-as-code - a polyglot journey.QAware GmbH
 

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

Building domain-specific languages with Groovy
Building domain-specific languages with GroovyBuilding domain-specific languages with Groovy
Building domain-specific languages with Groovy
 
Venkat Subramaniam Blending Java With Dynamic Languages
Venkat Subramaniam Blending Java With Dynamic LanguagesVenkat Subramaniam Blending Java With Dynamic Languages
Venkat Subramaniam Blending Java With Dynamic Languages
 
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume LaforgeGroovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
Groovy and Grails in Action - Devoxx 2008 - University - Guillaume Laforge
 
Groovy Finesse
Groovy FinesseGroovy Finesse
Groovy Finesse
 
Dynamic Languages on the JVM
Dynamic Languages on the JVMDynamic Languages on the JVM
Dynamic Languages on the JVM
 
Why don't you Groovy?
Why don't you Groovy?Why don't you Groovy?
Why don't you Groovy?
 
Groovy a Scripting Language for Java
Groovy a Scripting Language for JavaGroovy a Scripting Language for Java
Groovy a Scripting Language for Java
 
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume LaforgeGroovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
Groovy in the Enterprise - Case Studies - TSSJS Prague 2008 - Guillaume Laforge
 
Groovy introduction
Groovy introductionGroovy introduction
Groovy introduction
 
Step by Step Guide on Essay Format in APA For Beginners
Step by Step Guide on Essay Format in APA For BeginnersStep by Step Guide on Essay Format in APA For Beginners
Step by Step Guide on Essay Format in APA For Beginners
 
Java Programming
Java ProgrammingJava Programming
Java Programming
 
Build Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPCBuild Great Networked APIs with Swift, OpenAPI, and gRPC
Build Great Networked APIs with Swift, OpenAPI, and gRPC
 
One-stop solution for Grails web app development
One-stop solution for Grails web app developmentOne-stop solution for Grails web app development
One-stop solution for Grails web app development
 
Introduction to Java Programming.pdf
Introduction to Java Programming.pdfIntroduction to Java Programming.pdf
Introduction to Java Programming.pdf
 
OSGi enRoute Unveiled - P Kriens
OSGi enRoute Unveiled - P KriensOSGi enRoute Unveiled - P Kriens
OSGi enRoute Unveiled - P Kriens
 
JRuby in a Java World
JRuby in a Java WorldJRuby in a Java World
JRuby in a Java World
 
"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson"Xapi-lang For declarative code generation" By James Nelson
"Xapi-lang For declarative code generation" By James Nelson
 
NodeJS vs Golang - A detailed comparison
NodeJS vs Golang - A detailed comparisonNodeJS vs Golang - A detailed comparison
NodeJS vs Golang - A detailed comparison
 
Everything-as-code. A polyglot journey.
Everything-as-code. A polyglot journey.Everything-as-code. A polyglot journey.
Everything-as-code. A polyglot journey.
 
Everything-as-code - a polyglot journey.
Everything-as-code - a polyglot journey.Everything-as-code - a polyglot journey.
Everything-as-code - a polyglot journey.
 

More from Iván López Martín

SalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersSalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersIván López Martín
 
CommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 TestcontainersCommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 TestcontainersIván López Martín
 
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdfVoxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdfIván López Martín
 
VMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring BootVMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring BootIván López Martín
 
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud GatewaySpring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud GatewayIván López Martín
 
Codemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring BootCodemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring BootIván López Martín
 
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3Iván López Martín
 
Construyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVMConstruyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVMIván López Martín
 
jLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoTjLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoTIván López Martín
 
Codemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con MicronautCodemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con MicronautIván López Martín
 
JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!Iván López Martín
 
JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3Iván López Martín
 
JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3Iván López Martín
 
Developing Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEADeveloping Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEAIván López Martín
 
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfectaCommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfectaIván López Martín
 
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!Iván López Martín
 
Greach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsGreach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsIván López Martín
 
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet youVoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet youIván López Martín
 
JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!Iván López Martín
 
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerteCrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerteIván López Martín
 

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

SalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 TestcontainersSalmorejoTech 2024 - Spring Boot <3 Testcontainers
SalmorejoTech 2024 - Spring Boot <3 Testcontainers
 
CommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 TestcontainersCommitConf 2024 - Spring Boot <3 Testcontainers
CommitConf 2024 - Spring Boot <3 Testcontainers
 
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdfVoxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
Voxxed Days CERN 2024 - Spring Boot <3 Testcontainers.pdf
 
VMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring BootVMware - Testcontainers y Spring Boot
VMware - Testcontainers y Spring Boot
 
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud GatewaySpring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
Spring IO 2023 - Dynamic OpenAPIs with Spring Cloud Gateway
 
Codemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring BootCodemotion Madrid 2023 - Testcontainers y Spring Boot
Codemotion Madrid 2023 - Testcontainers y Spring Boot
 
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3CommitConf 2023 - Spring Framework 6 y Spring Boot 3
CommitConf 2023 - Spring Framework 6 y Spring Boot 3
 
Construyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVMConstruyendo un API REST con Spring Boot y GraalVM
Construyendo un API REST con Spring Boot y GraalVM
 
jLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoTjLove 2020 - Micronaut and graalvm: The power of AoT
jLove 2020 - Micronaut and graalvm: The power of AoT
 
Codemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con MicronautCodemotion Madrid 2020 - Serverless con Micronaut
Codemotion Madrid 2020 - Serverless con Micronaut
 
JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!JConf Perú 2020 - ¡Micronaut en acción!
JConf Perú 2020 - ¡Micronaut en acción!
 
JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3JConf Perú 2020 - Micronaut + GraalVM = <3
JConf Perú 2020 - Micronaut + GraalVM = <3
 
JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3JConf México 2020 - Micronaut + GraalVM = <3
JConf México 2020 - Micronaut + GraalVM = <3
 
Developing Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEADeveloping Micronaut Applications With IntelliJ IDEA
Developing Micronaut Applications With IntelliJ IDEA
 
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfectaCommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
CommitConf 2019 - Micronaut y GraalVm: La combinación perfecta
 
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
Codemotion Madrid 2019 - ¡GraalVM y Micronaut: compañeros perfectos!
 
Greach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut ConfigurationsGreach 2019 - Creating Micronaut Configurations
Greach 2019 - Creating Micronaut Configurations
 
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet youVoxxedDays Bucharest 2019 - Alexa, nice to meet you
VoxxedDays Bucharest 2019 - Alexa, nice to meet you
 
JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!JavaDay Lviv 2019 - Micronaut in action!
JavaDay Lviv 2019 - Micronaut in action!
 
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerteCrossDvlup Madrid 2019 - Alexa, encantado de conocerte
CrossDvlup Madrid 2019 - Alexa, encantado de conocerte
 

Recently uploaded

PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsStefano
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...Product School
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...Product School
 
Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationZilliz
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersSafe Software
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxJennifer Lim
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaCzechDreamin
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaRTTS
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomCzechDreamin
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Product School
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2DianaGray10
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Jeffrey Haguewood
 
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀DianaGray10
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Thierry Lestable
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCzechDreamin
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...Product School
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxAbida Shariff
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...Product School
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxDavid Michel
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoTAnalytics
 

Recently uploaded (20)

PLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. StartupsPLAI - Acceleration Program for Generative A.I. Startups
PLAI - Acceleration Program for Generative A.I. Startups
 
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
AI for Every Business: Unlocking Your Product's Universal Potential by VP of ...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Introduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG EvaluationIntroduction to Open Source RAG and RAG Evaluation
Introduction to Open Source RAG and RAG Evaluation
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptxWSO2CONMay2024OpenSourceConferenceDebrief.pptx
WSO2CONMay2024OpenSourceConferenceDebrief.pptx
 
Powerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara LaskowskaPowerful Start- the Key to Project Success, Barbara Laskowska
Powerful Start- the Key to Project Success, Barbara Laskowska
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone KomSalesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
Salesforce Adoption – Metrics, Methods, and Motivation, Antone Kom
 
Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...Designing Great Products: The Power of Design and Leadership by Chief Designe...
Designing Great Products: The Power of Design and Leadership by Chief Designe...
 
UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2UiPath Test Automation using UiPath Test Suite series, part 2
UiPath Test Automation using UiPath Test Suite series, part 2
 
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
Slack (or Teams) Automation for Bonterra Impact Management (fka Social Soluti...
 
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
Exploring UiPath Orchestrator API: updates and limits in 2024 🚀
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya HalderCustom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
Custom Approval Process: A New Perspective, Pavel Hrbacek & Anindya Halder
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptxUnpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
Unpacking Value Delivery - Agile Oxford Meetup - May 2024.pptx
 
IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024IoT Analytics Company Presentation May 2024
IoT Analytics Company Presentation May 2024
 

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 } }
  • 108.