Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

2,104 views

Published on

Groovy es un lenguaje dinámico para la JVM y la evolución natural para un programador Java debido a su baja curva de aprendizaje.

Si quieres saber por qué programar con Groovy es una Hora de Aventuras, esta es tu charla. Aprenderás a través de ejemplos las principales características que hacen de Groovy un lenguaje tan potente y versatil: tipado dinámico, closures, manejo de listas y mapas, power asserts, builders, metaprogramación, scripting, DSL's, transformaciones AST y muchas más.

Te aseguro que después de ella tendrás ganas de profundizar y utilizarlo en tu día a día.

Published in: Technology

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

  1. 1. De Java a Groovy: ¡Hora de Aventuras! Iván López @ilopmar
  2. 2. ➢ Iván López @ilopmar ➢ Groovy & Grails developer ➢ Coordinador de @madridgug ➢ Organizador de Greach @greachconf http://greachconf.com ➢ Speaker: SpringOne 2GX, GR8Conf, GGX, Codemotion, GeeCon, jDays, Spring IO, Greach, ConFess,... Sobre mí...
  3. 3. 1. Qué es Groovy
  4. 4. “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
  5. 5. “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
  6. 6. “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
  7. 7. “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
  8. 8. “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
  9. 9. “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
  10. 10. “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
  11. 11. “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
  12. 12. “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
  13. 13. “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
  14. 14. “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
  15. 15. Groovy
  16. 16. 2. ¿Y por qué no Java?
  17. 17. ➢ 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?
  18. 18. 3. Haciendo Java Groovy
  19. 19. 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.java Renombrar
  20. 20. 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
  21. 21. 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
  22. 22. 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
  23. 23. 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 setter verbosos Groovy
  24. 24. 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 como propiedad Groovy
  25. 25. 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
  26. 26. 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
  27. 27. 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 de colecciones Groovy
  28. 28. 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ón de String (GString) Groovy
  29. 29. 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
  30. 30. 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") } } tipado opcional Groovy
  31. 31. 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") } } named constructor Groovy
  32. 32. 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éntesis opcionales paréntesis opcionales Groovy
  33. 33. 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 como script Groovy
  34. 34. 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
  35. 35. class Saludador { String saludo void diHolaA(String... nombres) { println "$saludo ${nombres.join(', ')}!" } } saludador = new Saludador(saludo: 'Hola') saludador.diHolaA "Sheldon", "Leonard", "Raj", "Howard" Limpiemos los espacios Groovy
  36. 36. 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
  37. 37. 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%
  38. 38. Groovy: ¡Hora de Aventuras!
  39. 39. 4. Groovy
  40. 40. ➢ 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
  41. 41. 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; } }
  42. 42. 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 }
  43. 43. Named constructors class Persona { String nombre int edad } def p = new Persona(nombre: 'Iván', edad: 36) assert p.nombre == 'Iván' p.edad = 37 assert p.edad == 37
  44. 44. Constructor Builder import groovy.transform.builder.Builder @Builder class Persona { String nombre int edad } Persona.builder() .nombre('Iván') .edad(36) .build()
  45. 45. Números que... System.out.println(2.00 - 1.1); // 0.8999999999999999
  46. 46. Números que... System.out.println(2.00 - 1.1); // 0.8999999999999999
  47. 47. Números que... System.out.println(3 / 2); // 1
  48. 48. Números que... System.out.println(3 / 2); // 1
  49. 49. ¡BigDecimal por defecto! assert 2.0 - 1.1 == 0.9 assert 3 / 2 == 1.5
  50. 50. Equals y == estado != null && estado.equals(Estado.COMPLETADO);
  51. 51. Equals y == estado == Estado.COMPLETADO estado != null && estado.equals(Estado.COMPLETADO);
  52. 52. 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
  53. 53. 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
  54. 54. 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
  55. 55. 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
  56. 56. 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
  57. 57. Mapas def map = [nombre: 'Iván', edad: 36] assert map.nombre == 'Iván' map.hijas = ['Judith', 'Adriana'] assert map['hijas'].contains('Adriana')
  58. 58. 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')
  59. 59. Rangos def rango = 'a'..'z' assert rango.contains('i') assert rango.contains('z') def exclusivo = 1..<10 assert !exclusivo.contains(10) def inverso = 10..1 assert inverso[0] == 10 assert inverso[-1] == 1
  60. 60. Rangos def rango = 'a'..'z' assert rango.contains('i') assert rango.contains('z') def exclusivo = 1..<10 assert !exclusivo.contains(10) def inverso = 10..1 assert inverso[0] == 10 assert inverso[-1] == 1
  61. 61. Rangos def rango = 'a'..'z' assert rango.contains('i') assert rango.contains('z') def exclusivo = 1..<10 assert !exclusivo.contains(10) def inverso = 10..1 assert inverso[0] == 10 assert inverso[-1] == 1
  62. 62. Groovy truth assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  63. 63. Groovy truth false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  64. 64. 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 )
  65. 65. 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 )
  66. 66. Power asserts assert (2 + 7) * 5 != (2 * 5) + (7 * 5) (2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35
  67. 67. Power asserts assert (2 + 7) * 5 != (2 * 5) + (7 * 5) (2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35
  68. 68. 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]]]
  69. 69. 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]]]
  70. 70. 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]]]
  71. 71. 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]]]
  72. 72. 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]]]
  73. 73. 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
  74. 74. Elvis List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList();
  75. 75. Elvis List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList(); def resultado = nombres ? nombres : []
  76. 76. Elvis List resultado = (nombres != null && nombres.size() > 0) ? nombres : Collections.emptyList(); def resultado = nombres ? nombres : [] def resultado = nombres ?: []
  77. 77. Safe navigation if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } }
  78. 78. Safe navigation if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } } println order?.customer?.address
  79. 79. Closures def multiplicador = { a, b -> a * b } assert multiplicador(2, 3) == 6 assert multiplicador.call(2, 3) == 6 assert multiplicador('=', 8) == '========' def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplicador = { int a, int b -> a * b }
  80. 80. def multiplicador = { a, b -> a * b } assert multiplicador(2, 3) == 6 assert multiplicador.call(2, 3) == 6 assert multiplicador('=', 8) == '========' def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplicador = { int a, int b -> a * b } Closures
  81. 81. def multiplicador = { a, b -> a * b } assert multiplicador(2, 3) == 6 assert multiplicador.call(2, 3) == 6 assert multiplicador('=', 8) == '========' def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplicador = { int a, int b -> a * b } Closures
  82. 82. Closures: Valores por defecto def multiplicador = { int a, int b = 10 -> a * b } assert multiplicador(2, 3) == 6 assert multiplicador(2) == 20
  83. 83. Closures: Métodos como función def logBase10 = Math.&log10 assert logBase10(10) == 1
  84. 84. 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'
  85. 85. 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'
  86. 86. 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'
  87. 87. Groovy Closures y Java 8 Lambdas import static java.util.Arrays.asList; public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); } }
  88. 88. Groovy Closures y Java 8 Lambdas import static java.util.Arrays.asList; public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); } } [1, 2, 3].stream() .map { i -> i * 2 } .filter { i -> i > 3 } .findFirst() .orElseThrow(IllegalArgumentException.&newInstance)
  89. 89. 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()
  90. 90. 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()
  91. 91. Parsear XML y Json en Java
  92. 92. 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 },
  93. 93. Json parser http://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 },
  94. 94. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Leganes&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC { weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes", }
  95. 95. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Leganes&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC { weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes", }
  96. 96. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Leganes&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC { weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes", }
  97. 97. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Leganes&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Tiempo en Leganes (ES): few clouds. Temp: 8.21 ºC { weather: [ { description: "few clouds", } ], main: { temp: 8.21 }, sys: { country: "ES", }, name: "Leganes", }
  98. 98. 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(); } }
  99. 99. 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
  100. 100. 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
  101. 101. Lectura de una URL import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
  102. 102. Lectura de una URL import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } println 'http://www.google.com'.toURL().text
  103. 103. Lectura de una URL import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } println 'http://www.google.com'.toURL().text
  104. 104. ➢ Groovy JDK ➢ Amplía tipos ➢ Añade métodos ➢ http://www.groovy-lang.org/gdk.html GDK
  105. 105. 5. ¡Quiero más!
  106. 106. 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)
  107. 107. 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)
  108. 108. DSLs: Domain Specific Languages mail { 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() }
  109. 109. DSLs: Domain Specific Languages mail { 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() }
  110. 110. DSLs: Domain Specific Languages mail { 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() }
  111. 111. ➢ +50 trasformación out-of-the-box ➢ @ToString, @EqualsAndHashCode, @InheritConstructors, @Sortable, @Delegate, @Immutable, @CompileStatic,... Transformaciones AST
  112. 112. @EqualsAndHashCode public 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 } }
  113. 113. @EqualsAndHashCode @groovy.transform.EqualsAndHashCode class User { String name Integer age }
  114. 114. ¡Gracias!
  115. 115. ¡Gracias! ¿Preguntas? @ilopmar lopez.ivan@gmail.com https://github.com/ilopmar Iván López http://bit.ly/t3chfest-groovy

×