De Java a Groovy:¡Hora de Aventuras!Iván López @ilopmar
➢ Iván López @ilopmar
➢ Groovy & Grails developer
➢ Coordinador de @madridgug
➢ Organizador de Greach@greachconfhttp://greachconf.com
➢ Speaker: SpringOne 2GX, GR8Conf,GGX, Codemotion, GeeCon, jDays,Spring IO, Greach, ConFess,...
Sobre mí...
1.Qué es Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
“Groovy es un lenguaje dinámico poderoso, opcionalmente tipado, con capacidad de tipado y compilación estáticos para la plataforma Java centrado en multiplicar la productividad de los desarrolladores gracias a una sintaxis concisa, familiar y fácil de aprender.
Se integra sin problemas con cualquier programa Java e inmediatamente proporciona a tu aplicación poderosas características como capacidades de scripting, DSLs, metaprogramación en runtime y compile-time y programación funcional.
– Web de Groovy
Groovy
2.¿Y por qué no Java?
➢ Java es sólido
➢ Conocido por muchos desarrolladores
➢ Muy extendido
➢ Es rápido
Pero...
➢ Java es verboso
➢ Puede ser incómodo en algunos casos
➢ No es dinámico
¿Y por qué no Java?
3.Haciendo Java Groovy
public class Saludador { private String saludo;
public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres); System.out.println(mensajeSaludo); }
public String getSaludo() { return saludo; }
public void setSaludo(String saludo) { this.saludo = saludo; }
private String prepararMensajeSaludo(String... nombres) { String delimitador = ""; StringBuilder sb = new StringBuilder(); for (String nombre : nombres) { sb.append(delimitador).append(nombre); delimitador = ", "; } return this.saludo + " " + sb.toString() + "!"; }
public static void main(String[] args) { final Saludador saludador = new Saludador(); saludador.setSaludo("Hola"); saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard"); }}
Saludador.javaRenombrar
public class Saludador { private String saludo;
public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres); System.out.println(mensajeSaludo); }
public String getSaludo() { return saludo; }
public void setSaludo(String saludo) { this.saludo = saludo; }
private String prepararMensajeSaludo(String... nombres) { String delimitador = ""; StringBuilder sb = new StringBuilder(); for (String nombre : nombres) { sb.append(delimitador).append(nombre); delimitador = ", "; } return this.saludo + " " + sb.toString() + "!"; }
public static void main(String[] args) { final Saludador saludador = new Saludador(); saludador.setSaludo("Hola"); saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard"); }}
Saludador.groovy
public class Saludador { private String saludo;
public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres); System.out.println(mensajeSaludo); }
public String getSaludo() { return saludo; }
public void setSaludo(String saludo) { this.saludo = saludo; }
private String prepararMensajeSaludo(String... nombres) { String delimitador = ""; StringBuilder sb = new StringBuilder(); for (String nombre : nombres) { sb.append(delimitador).append(nombre); delimitador = ", "; } return this.saludo + " " + sb.toString() + "!"; }
public static void main(String[] args) { final Saludador saludador = new Saludador(); saludador.setSaludo("Hola"); saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard"); }}
Groovy
public class Saludador { private String saludo
public void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }
public String getSaludo() { return saludo }
public void setSaludo(String saludo) { this.saludo = saludo }
private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }
public static void main(String[] args) { final Saludador saludador = new Saludador() saludador.setSaludo("Hola") saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
opcional
opcional
Groovy
class Saludador { private String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }
String getSaludo() { return saludo }
void setSaludo(String saludo) { this.saludo = saludo }
private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.setSaludo("Hola") saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
getter y setterverbosos
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.setSaludo("Hola") saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
Acceso comopropiedad
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } return this.saludo + " " + sb.toString() + "!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
opcional
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) System.out.println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } this.saludo + " " + sb.toString() + "!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
atajo
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { String delimitador = "" StringBuilder sb = new StringBuilder() for (String nombre : nombres) { sb.append(delimitador).append(nombre) delimitador = ", " } this.saludo + " " + sb.toString() + "!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
API decolecciones
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { String nombreUnidos = nombres.join(', ') this.saludo + " " + nombresUnidos + "!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
interpolaciónde String (GString)
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { String nombreUnidos = nombres.join(', ')
"${this.saludo} $nombreUnidos!" }
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
refactor
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { String mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"
}
static void main(String[] args) { final Saludador saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
tipadoopcional
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"
}
static void main(String[] args) { def saludador = new Saludador() saludador.saludo = "Hola" saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
namedconstructor
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println(mensajeSaludo) }
private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"
}
static void main(String[] args) { def saludador = new Saludador(saludo: 'Hola') saludador.diHolaA("Sheldon", "Leonard", "Raj", "Howard") }}
paréntesisopcionales
paréntesisopcionales
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println mensajeSaludo }
private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"
}
static void main(String[] args) { def saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard" }}
main comoscript
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { def mensajeSaludo = prepararMensajeSaludo(nombres) println mensajeSaludo }
private String prepararMensajeSaludo(String... nombres) { "$saludo ${nombres.join(', ')}!"
}} saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"
refactor
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" }
} saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"
Limpiemoslos espacios
Groovy
class Saludador { String saludo
void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" }}
saludador = new Saludador(saludo: 'Hola')saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"
Groovy: Versión final
class Saludador { String saludo
void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" }}
saludador = new Saludador(saludo: 'Hola')saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard"
Groovy: Versión final
Java 32 líneas 900 caracteres
Groovy 10 líneas 231 caracteres
Diferencia 68% 74%
Groovy: ¡Hora de Aventuras!
4.Groovy
➢ Dinámico
➢ Compilación estática opcional
➢ Todo es un objeto
➢ Sobrecarga de operadores➢ + es .plus()➢ * es .multiply()
➢ Sintaxis nativa de listas, mapas y rangos
➢ Métodos y clases public por defecto
➢ Las excepciones son unchecked
➢ http://groovy-lang.org/differences.html
Diferencias entre Java y Groovy
Getters y setters
public class Persona {
private String nombre; private int edad;
String getNombre() { return nombre; }
void setNombre(String nombre) { this.nombre = nombre; }
int getEdad() { return edad; }
void setEdad(int edad) { this.edad = edad; }}
Getters y setters
public class Persona {
private String nombre; private int edad;
String getNombre() { return nombre; }
void setNombre(String nombre) { this.nombre = nombre; }
int getEdad() { return edad; }
void setEdad(int edad) { this.edad = edad; }}
class Persona { String nombre int edad}
Named constructors
class Persona { String nombre int edad}
def p = new Persona(nombre: 'Iván', edad: 36)assert p.nombre == 'Iván'
p.edad = 37assert p.edad == 37
Constructor Builder
import groovy.transform.builder.Builder
@Builderclass Persona { String nombre int edad}
Persona.builder() .nombre('Iván') .edad(36) .build()
Números que...
System.out.println(2.00 - 1.1);// 0.8999999999999999
Números que...
System.out.println(2.00 - 1.1);// 0.8999999999999999
Números que...
System.out.println(3 / 2);// 1
Números que...
System.out.println(3 / 2);// 1
¡BigDecimal por defecto!
assert 2.0 - 1.1 == 0.9assert 3 / 2 == 1.5
Equals y ==
estado != null && estado.equals(Estado.COMPLETADO);
Equals y ==
estado == Estado.COMPLETADO
estado != null && estado.equals(Estado.COMPLETADO);
Strings y GString
def nombre = 'Iván'def edad = 36
println "¡Hola ${nombre}, tienes ${edad} años!"
def query = """insert into people (firstName, age)values (${nombre}, ${edad})"""
new Sql(datasource).execute query
Strings y GString
def nombre = 'Iván'def edad = 36
println "¡Hola ${nombre}, tienes ${edad} años!"
def query = """insert into people (firstName, age)values (${nombre}, ${edad})"""
new Sql(datasource).execute query
Listas
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
Listas
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
Listas
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
Mapas
def map = [nombre: 'Iván', edad: 36]assert map.nombre == 'Iván'
map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')
Mapas
def map = [nombre: 'Iván', edad: 36]assert map.nombre == 'Iván'
map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')
def map = [nombre: 'Iván', edad: 36]assert map.nombre == 'Iván'
map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')
Rangos
def rango = 'a'..'z'assert rango.contains('i')assert rango.contains('z')
def exclusivo = 1..<10assert !exclusivo.contains(10)
def inverso = 10..1assert inverso[0] == 10assert inverso[-1] == 1
Rangos
def rango = 'a'..'z'assert rango.contains('i')assert rango.contains('z')
def exclusivo = 1..<10assert !exclusivo.contains(10)
def inverso = 10..1assert inverso[0] == 10assert inverso[-1] == 1
Rangos
def rango = 'a'..'z'assert rango.contains('i')assert rango.contains('z')
def exclusivo = 1..<10assert !exclusivo.contains(10)
def inverso = 10..1assert inverso[0] == 10assert inverso[-1] == 1
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
false
true
assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )
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 = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]
assert info.hijas.nombre.first() == 'Adriana'
info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]
Power asserts
def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]
assert info.hijas.nombre.first() == 'Adriana'
info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]
Power asserts
def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]
assert info.hijas.nombre.first() == 'Adriana'
info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]
Power asserts
def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]
assert info.hijas.nombre.first() == 'Adriana'
info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]
Power asserts
def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]
assert info.hijas.nombre.first() == 'Adriana'
info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]
def info = [ nombre: 'Iván', edad: 36, hijas: [ [nombre: 'Judith', edad: 8], [nombre: 'Adriana', edad: 5] ]]
assert info.hijas.nombre.first() == 'Adriana'
info.hijas.nombre.first() == 'Adriana'| | | | || | | Judith false| | | 6 differences (14% similarity)| | | (Ju)d(-)i(th-)| | | (A-)d(r)i(ana)| | [Judith, Adriana]| [[nombre:Judith, edad:8], [nombre:Adriana, edad:5]][nombre:Iván, edad:36, hijas:[[nombre:Judith, edad:8], [nombre:Adriana, edad:5]]]
Power asserts
Elvis
List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();
Elvis
List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();
def resultado = nombres ? nombres : []
Elvis
List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();
def resultado = nombres ? nombres : []
def resultado = nombres ?: []
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 multiplicador = { a, b -> a * b }
assert multiplicador(2, 3) == 6assert multiplicador.call(2, 3) == 6assert multiplicador('=', 8) == '========'
def sumador = { ... numbers -> numbers.sum() }assert sumador(1, 2, 3) == 6assert sumador('a', 'b', 'c') == 'abc'
def multiplicador = { int a, int b -> a * b }
def multiplicador = { a, b -> a * b }
assert multiplicador(2, 3) == 6assert multiplicador.call(2, 3) == 6assert multiplicador('=', 8) == '========'
def sumador = { ... numbers -> numbers.sum() }assert sumador(1, 2, 3) == 6assert sumador('a', 'b', 'c') == 'abc'
def multiplicador = { int a, int b -> a * b }
Closures
def multiplicador = { a, b -> a * b }
assert multiplicador(2, 3) == 6assert multiplicador.call(2, 3) == 6assert multiplicador('=', 8) == '========'
def sumador = { ... numbers -> numbers.sum() }assert sumador(1, 2, 3) == 6assert sumador('a', 'b', 'c') == 'abc'
def multiplicador = { int a, int b -> a * b }
Closures
Closures: Valores por defecto
def multiplicador = { int a, int b = 10 -> a * b }
assert multiplicador(2, 3) == 6assert multiplicador(2) == 20
Closures: Métodos como función
def logBase10 = Math.&log10assert logBase10(10) == 1
Closures: map, filter, reduce
def personas = [ new Persona('Iván', 36), new Persona('Judith', 8), new Persona('Adriana', 5)]
def nombres = personas.findAll { it.edad < 18 } .collect { it.nombre.toUpperCase() } .sort() .join(', ')
assert nombres == 'ADRIANA, JUDITH'
Closures: map, filter, reduce
def personas = [ new Persona('Iván', 36), new Persona('Judith', 8), new Persona('Adriana', 5)]
def nombres = personas.findAll { it.edad < 18 } .collect { it.nombre.toUpperCase() } .sort() .join(', ')
assert nombres == 'ADRIANA, JUDITH'
Closures: map, filter, reduce
def personas = [ new Persona('Iván', 36), new Persona('Judith', 8), new Persona('Adriana', 5)]
def nombres = personas.findAll { it.edad < 18 } .collect { it.nombre.toUpperCase() } .sort() .join(', ')
assert nombres == 'ADRIANA, JUDITH'
Groovy Closures y Java 8 Lambdasimport 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); }}
Groovy Closures y Java 8 Lambdasimport 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)
Json builder
{ "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "T3chFest", "Codemotion", "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
{ "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "T3chFest", "Codemotion", "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()
Parsear XML y Json en Java
Json parser
wind: { speed: 2.1, deg: 350 }, clouds: { all: 75 }, dt: 1454061483, sys: { type: 1, id: 5488, message: 0.0046, country: "ES", sunrise: 1454052430, sunset: 1454088574 }, id: 3118594, name: "Leganes", cod: 200}
http://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...
{ coord: { lon: -3.76, lat: 40.33 }, weather: [ { id: 300, main: "Drizzle", description: "few clouds", icon: "09d" } ], base: "cmc stations", main: { temp: 8.21, pressure: 1032, humidity: 87, temp_min: 8, temp_max: 8.6 },
Json parserhttp://api.openweathermap.org/data/2.5/weather?units=metric&q=Leganes&appid=...
wind: { speed: 2.1, deg: 350 }, clouds: { all: 75 }, dt: 1454061483, sys: { type: 1, id: 5488, message: 0.0046, country: "ES", sunrise: 1454052430, sunset: 1454088574 }, id: 3118594, name: "Leganes", cod: 200}
{ coord: { lon: -3.76, lat: 40.33 }, weather: [ { id: 300, main: "Drizzle", description: "few clouds", icon: "09d" } ], base: "cmc stations", main: { temp: 8.21, pressure: 1032, humidity: 87, temp_min: 8, temp_max: 8.6 },
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.countryString temp = response.main.tempString 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: 8.21 }, sys: { country: "ES", }, name: "Leganes",}
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.countryString temp = response.main.tempString 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: 8.21 }, sys: { country: "ES", }, name: "Leganes",}
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.countryString temp = response.main.tempString 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: 8.21 }, sys: { country: "ES", }, name: "Leganes",}
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.countryString temp = response.main.tempString city = response.name
println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC"
// Tiempo en Leganes (ES): few clouds. Temp: 8.21 ºC
{ weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes",}
Lectura de fichero de texto
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(); }}
Lectura de fichero de texto
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.txt').text
Lectura de fichero de texto
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.txt').text
Lectura de una URLimport 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(); } }}
Lectura de una URLimport 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
Lectura de una URLimport 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
➢ Groovy JDK
➢ Amplía tipos
➢ Añade métodos
➢ http://www.groovy-lang.org/gdk.html
GDK
5.¡Quiero más!
DSLs: Domain Specific Languages
def mailer = new Mailer()mailer.setTo('[email protected]', '[email protected]')mailer.setSubject('Urgente!')mailer.setBody('Bla, bla, bla')mailer.setHeaders(spam: 'no', important: true)
DSLs: Domain Specific Languages
def mailer = new Mailer()mailer.setTo('[email protected]', '[email protected]')mailer.setSubject('Urgente!')mailer.setBody('Bla, bla, bla')mailer.setHeaders(spam: 'no', important: true)
def mailer = new Mailer() .setTo('[email protected]', '[email protected]') .setSubject('Urgente!') .setBody('Bla, bla, bla') .setHeaders(spam: 'no', important: true)
DSLs: Domain Specific Languagesmail { to '[email protected]', '[email protected]' subject 'Urgente!' 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) { // Igual que: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl()}
DSLs: Domain Specific Languagesmail { to '[email protected]', '[email protected]' subject 'Urgente!' 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) { // Igual que: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl()}
DSLs: Domain Specific Languagesmail { to '[email protected]', '[email protected]' subject 'Urgente!' 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) { // Igual que: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl()}
➢ +50 trasformación out-of-the-box
➢ @ToString, @EqualsAndHashCode, @InheritConstructors,
@Sortable, @Delegate, @Immutable, @CompileStatic,...
Transformaciones AST
@EqualsAndHashCodepublic class User extends java.lang.Object {
private java.lang.String name private java.lang.Integer age
public int hashCode() { java.lang.Object _result = org.codehaus.groovy.util.HashCodeHelper.initHash() if (!(this.getName().is(this))) { _result = org.codehaus.groovy.util.HashCodeHelper.updateHash(_result, this.getName()) } if (!(this.getAge().is(this))) { _result = org.codehaus.groovy.util.HashCodeHelper.updateHash(_result, this.getAge()) } return _result }
public boolean canEqual(java.lang.Object other) { return other instanceof User }
public boolean equals(java.lang.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.EqualsAndHashCodeclass User { String name Integer age}
¡Gracias!
¡Gracias!¿Preguntas?
@ilopmar
https://github.com/ilopmar
Iván López
http://bit.ly/t3chfest-groovy
Top Related