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

105
De Java a Groovy: ¡Hora de aventuras! by Iván López - @ilopmar

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

Page 1: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

De Java a Groovy: ¡Hora de aventuras!

by Iván López - @ilopmar

Page 2: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ Iván López @ilopmar

➢ Desarrollador Groovy & GrailsMiembro del equipo de Grailsen OCI

➢ Coordinador de @madridgughttp://madridgug.com

➢ Organizador de Greach@greachconfhttp://greachconf.com

➢ Speaker: SpringOne 2GX, GR8Conf,GGX, Codemotion, GeeCon, JavaCro,Spring IO, Greach, ConFoo, RigaDevDays,...

Sobre mí...

Page 3: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

1.Qué es Groovy

Page 4: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 5: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 6: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 7: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 8: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 9: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 10: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 11: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 12: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 13: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 14: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

“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

Page 15: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy

Page 16: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

2.¿Y por qué no Java?

Page 17: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ 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?

Page 18: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

3.Haciendo Java Groovy

Page 19: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 20: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 21: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 22: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 23: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 24: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 25: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 26: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 27: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 28: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 29: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 30: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 31: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 32: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 33: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 34: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 35: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 36: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 37: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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%

Page 38: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy: ¡Hora de Aventuras!

Page 39: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

4.Groovy

Page 40: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ 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

Page 41: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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; }}

Page 42: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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}

Page 43: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 44: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Constructor Builder

import groovy.transform.builder.Builder

@Builderclass Persona { String nombre int edad}

Persona.builder() .nombre('Iván') .edad(36) .build()

Page 45: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 46: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 47: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(2.00 - 1.1);// 0.8999999999999999

Page 48: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(2.00 - 1.1);// 0.8999999999999999

Page 49: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(3 / 2);// 1

Page 50: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Números que...

System.out.println(3 / 2);// 1

Page 51: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

¡BigDecimal por defecto!

assert 2.0 - 1.1 == 0.9assert 3 / 2 == 1.5

Page 52: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Equals y ==

estado != null && estado.equals(Estado.COMPLETADO);

Page 53: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Equals y ==

estado == Estado.COMPLETADO

estado != null && estado.equals(Estado.COMPLETADO);

Page 54: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Listas

def list = ['a', 'b', 'c'] // ArrayList

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

Page 55: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Listas

def list = ['a', 'b', 'c'] // ArrayList

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

Page 56: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Listas

def list = ['a', 'b', 'c'] // ArrayList

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

Page 57: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Mapas

def map = [nombre: 'Iván', edad: 36] // HashMapassert map.nombre == 'Iván'assert map.get('nombre') == 'Iván'assert map['nombre'] == 'Iván'

map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')

Page 58: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Mapas

def map = [nombre: 'Iván', edad: 36] // HashMapassert map.nombre == 'Iván'assert map.get('nombre') == 'Iván'assert map['nombre'] == 'Iván'

map.hijas = ['Judith', 'Adriana']assert map['hijas'].contains('Adriana')

Page 59: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 60: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 61: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 62: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

assert (2 + 7) * 5 != (2 * 5) + (7 * 5)

(2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35

Page 63: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Power asserts

assert (2 + 7) * 5 != (2 * 5) + (7 * 5)

(2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35

Page 64: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy truth

assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )

Page 65: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Groovy truth

false

assert !( null )assert !( "" )assert !( '' )assert !( [] )assert !( [:] )assert !( 0 )

Page 66: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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 )

Page 67: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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 )

Page 68: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Elvis

List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();

Page 69: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Elvis

List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();

def resultado = nombres ? nombres : []

Page 70: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Elvis

List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();

def resultado = nombres ? nombres : []

def resultado = nombres ?: []

Page 71: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Safe navigation

if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } }}

Page 72: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Safe navigation

if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } }}

println order?.customer?.address

Page 73: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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 }

Page 74: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 75: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 76: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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); }}

Page 77: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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)

Page 78: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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()

Page 79: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json builder

{ "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "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( 'Codemotion', 'Greach' ) }

println builder.toPrettyString()

Page 80: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Parsear XML y Json en Java

Page 81: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

wind: { speed: 3.6, deg: 270 }, clouds: { all: 20 }, dt: 1478604600, sys: { message: 0.0098, country: "ES", sunrise: 1478588020, sunset: 1478624582 }, id: 3117735, name: "Madrid", cod: 200}

http://api.openweathermap.org/data/2.5/weather?units=metric&q=Madrid&appid=...

{ coord: { lon: -3.7, lat: 40.42 }, weather: [ { id: 801, main: "Clouds", description: "few clouds", icon: "02d" } ], base: "stations", main: { temp: 9.38, pressure: 1022, humidity: 43, temp_min: 9, temp_max: 10 },

Page 82: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parserhttp://api.openweathermap.org/data/2.5/weather?units=metric&q=Madrid&appid=...

{ coord: { lon: -3.7, lat: 40.42 }, weather: [ { id: 801, main: "Clouds", description: "few clouds", icon: "02d" } ], base: "stations", main: { temp: 9.38, pressure: 1022, humidity: 43, temp_min: 9, temp_max: 10 },

wind: { speed: 3.6, deg: 270 }, clouds: { all: 20 }, dt: 1478604600, sys: { message: 0.0098, country: "ES", sunrise: 1478588020, sunset: 1478624582 }, id: 3117735, name: "Madrid", cod: 200}

Page 83: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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: 9.38 }, sys: { country: "ES", }, name: "Madrid",}

Page 84: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Madrid&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 Madrid (ES): few clouds. Temp: 9.38 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 9.38 }, sys: { country: "ES", }, name: "Madrid",}

Page 85: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Madrid&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 Madrid (ES): few clouds. Temp: 9.38 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 9.38 }, sys: { country: "ES", }, name: "Madrid",}

Page 86: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

Json parser

import groovy.json.JsonSlurper

def url = "http://api.openweathermap.org/data/2.5/weather?units=metric&q=Madrid&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 Madrid (ES): few clouds. Temp: 9.38 ºC

{ weather: [ { description: "few clouds", } ], main: { temp: 9.38 }, sys: { country: "ES", }, name: "Madrid",}

Page 87: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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(); }}

Page 88: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 89: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 90: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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(); } }}

Page 91: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 92: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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

Page 93: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ Groovy JDK

➢ Amplía tipos

➢ Añade métodos

➢ http://www.groovy-lang.org/gdk.html

GDK

Page 94: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

5.¡Quiero más!

Page 95: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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)

Page 96: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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)

Page 97: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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()}

Page 98: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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()}

Page 99: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

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()}

Page 100: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

➢ +50 trasformación out-of-the-box

➢ @ToString, @EqualsAndHashCode, @InheritConstructors,

@Sortable, @Delegate, @Immutable, @CompileStatic,...

Transformaciones AST

Page 101: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

@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 }}

Page 102: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

@EqualsAndHashCode

@groovy.transform.EqualsAndHashCodeclass User { String name Integer age}

Page 103: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

¡Gracias!

Page 104: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

¡Gracias!¿Preguntas?

@ilopmar

[email protected]

https://github.com/ilopmar

Iván López

http://bit.ly/java-a-groovy

Page 105: Codemotion Madrid 2016 - De Java a Groovy: ¡Hora de Aventuras!

¿Es Groovy lento?

➢ ¡Lo era!

➢ InvokeDynamic de JDK7

➢ @CompileStatic añadido en 2.0

➢ Actualmente Groovy + @CompileStatic ≈ Java