T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

Post on 14-Apr-2017

1.891 views 0 download

Transcript of T3chFest 2016 - De Java a Groovy: ¡Hora de Aventuras!

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('admin@example.com', 'user@example.com')mailer.setSubject('Urgente!')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('Urgente!')mailer.setBody('Bla, bla, bla')mailer.setHeaders(spam: 'no', important: true)

def mailer = new Mailer() .setTo('admin@example.com', 'user@example.com') .setSubject('Urgente!') .setBody('Bla, bla, bla') .setHeaders(spam: 'no', important: true)

DSLs: Domain Specific Languagesmail { to 'admin@example.com', 'user@example.com' 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 'admin@example.com', 'user@example.com' 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 'admin@example.com', 'user@example.com' 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

lopez.ivan@gmail.com

https://github.com/ilopmar

Iván López

http://bit.ly/t3chfest-groovy