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.

JavaCro 2016 - From Java to Groovy: Adventure Time!

1,667 views

Published on

Groovy is a dynamic language for the JVM and the natural evolution for a Java developer because its flat learning curve. If you want to know why developing with Groovy is an Adventure Time, this is your talk. You'll learn with examples the main characteristics that make Groovy a powerful and versatile language: dynamic typing, closures, lists and maps handling, power asserts, builders, metaprogramming, scripting, DSL's, AST transformations,... and many more.I can guarantee you that after the talk you'll want to learn more about Groovy and use it in your day at work.

Published in: Technology

JavaCro 2016 - From Java to Groovy: Adventure Time!

  1. 1. From Java to Groovy: Adventure Time! Iván López @ilopmar
  2. 2. ➢ Iván López @ilopmar ➢ Groovy & Grails developer ➢ @MadridGUG coordinator ➢ Greach organizer @greachconf http://greachconf.com ➢ Speaker: SpringOne 2GX, GR8Conf, GGX, Codemotion, GeeCon, jDays, Spring IO, Greach, ConFoo, ConFess, RigaDevDays... About me...
  3. 3. 1. What is Groovy?
  4. 4. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  5. 5. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  6. 6. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  7. 7. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  8. 8. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  9. 9. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  10. 10. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  11. 11. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  12. 12. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  13. 13. “Apache Groovy is a powerful, optionally typed and dynamic language, with static-typing and static compilation capabilities, for the Java platform aimed at improving developer productivity thanks to a concise, familiar and easy to learn syntax. It integrates smoothly with any Java program, and immediately delivers to your application powerful features, including scripting capabilities, Domain-Specific Language authoring, runtime and compile-time meta-programming and functional programming. – Groovy website
  14. 14. Groovy
  15. 15. 2. Why not Java?
  16. 16. ➢ Java is solid ➢ Known by a lot of developers ➢ Used everywhere ➢ Is fast But... ➢ Java is verbose ➢ Can be annoying ➢ It's not dynamic Why not Java?
  17. 17. 3. Making Java Groovy
  18. 18. Greeter.java public class Greeter { private String greeting; public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names); System.out.println(helloMessage); } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } private String prepareHelloMessage(String... names) { String delimiter = ""; StringBuilder sb = new StringBuilder(); for (String name : names) { sb.append(delimiter).append(name); delimiter = ", "; } return this.greeting + " " + sb.toString() + "!"; } public static void main(String[] args) { final Greeter greeter = new Greeter(); greeter.setGreeting("Hi"); greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard"); } } Rename
  19. 19. public class Greeter { private String greeting; public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names); System.out.println(helloMessage); } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } private String prepareHelloMessage(String... names) { String delimiter = ""; StringBuilder sb = new StringBuilder(); for (String name : names) { sb.append(delimiter).append(name); delimiter = ", "; } return this.greeting + " " + sb.toString() + "!"; } public static void main(String[] args) { final Greeter greeter = new Greeter(); greeter.setGreeting("Hi"); greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard"); } } Greeter.groovy
  20. 20. Groovy public class Greeter { private String greeting; public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names); System.out.println(helloMessage); } public String getGreeting() { return greeting; } public void setGreeting(String greeting) { this.greeting = greeting; } private String prepareHelloMessage(String... names) { String delimiter = ""; StringBuilder sb = new StringBuilder(); for (String name : names) { sb.append(delimiter).append(name); delimiter = ", "; } return this.greeting + " " + sb.toString() + "!"; } public static void main(String[] args) { final Greeter greeter = new Greeter(); greeter.setGreeting("Hi"); greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard"); } }
  21. 21. optional public class Greeter { private String greeting public void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } public String getGreeting() { return greeting } public void setGreeting(String greeting) { this.greeting = greeting } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } public static void main(String[] args) { final Greeter greeter = new Greeter() greeter.setGreeting("Hi") greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } optional Groovy
  22. 22. verbose getter/setter Groovy class Greeter { private String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } String getGreeting() { return greeting } void setGreeting(String greeting) { this.greeting = greeting } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.setGreeting("Hi") greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } }
  23. 23. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.setGreeting("Hi") greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } Accessing as property Groovy
  24. 24. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } return this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } optional Groovy
  25. 25. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) System.out.println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } shortcut Groovy
  26. 26. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { String delimiter = "" StringBuilder sb = new StringBuilder() for (String name : names) { sb.append(delimiter).append(name) delimiter = ", " } this.greeting + " " + sb.toString() + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } Collections API Groovy
  27. 27. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { String joinedNames = names.join(', ') this.greeting + " " + joinedNames + "!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } String interpolation (GString) Groovy
  28. 28. class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { String joinedNames = names.join(', ') "${this.greeting} $joinedNames!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } refactor Groovy
  29. 29. optional typing Groovy class Greeter { String greeting void sayHiTo(String... names) { String helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { final Greeter greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } }
  30. 30. class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { def greeter = new Greeter() greeter.greeting = "Hi" greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } } named constructor Groovy
  31. 31. optional parentheses optional parentheses Groovy class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println(helloMessage) } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { def greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo("Sheldon", "Leonard", "Raj", "Howard") } }
  32. 32. main as script Groovy class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println helloMessage } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } static void main(String[] args) { def greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" } }
  33. 33. class Greeter { String greeting void sayHiTo(String... names) { def helloMessage = prepareHelloMessage(names) println helloMessage } private String prepareHelloMessage(String... names) { "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" refactor Groovy
  34. 34. class Greeter { String greeting void sayHiTo(String... names) { println "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" Let's clean the empty spaces Groovy
  35. 35. class Greeter { String greeting void sayHiTo(String... names) { println "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard" Groovy: Final version
  36. 36. Groovy: Final version Java 32 lines of code 880 characters Groovy 10 lines of code 221 characters Difference 69% 75% class Greeter { String greeting void sayHiTo(String... names) { println "$greeting ${names.join(', ')}!" } } greeter = new Greeter(greeting: 'Hi') greeter.sayHiTo "Sheldon", "Leonard", "Raj", "Howard"
  37. 37. Groovy: Adventure Time!
  38. 38. 4. Groovy
  39. 39. ➢ Dynamic ➢ Optional static compilation ➢ Everything is an object ➢ Operator overloading ➢ + is a call to .plus() ➢ * is a call to .multiply() ➢ Native syntax for lists, maps and ranges ➢ Methods and classes are public by default ➢ All exceptions are unchecked ➢ http://groovy-lang.org/differences.html Differences between Java and Groovy
  40. 40. Getters y setters public class Person { private String name; private int age; String getName() { return name; } void setName(String name) { this.name = name; } int getAge() { return age; } void setAge(int age) { this.age = age; } }
  41. 41. Getters y setters class Person { String name int age } public class Person { private String name; private int age; String getName() { return name; } void setName(String name) { this.name = name; } int getAge() { return age; } void setAge(int age) { this.age = age; } }
  42. 42. Named constructors class Person { String name int age } def p = new Person(name: 'Iván', age: 36) assert p.name == 'Iván' p.age = 37 assert p.age == 37
  43. 43. Constructor Builder import groovy.transform.builder.Builder @Builder class Person { String name int age } Person.builder() .name('Iván') .age(36) .build()
  44. 44. Strings and GStrings def name = 'Iván' def age = 36 println "¡Hi ${name}, you are ${age} years old!" def query = """ insert into people (firstName, age) values (${name}, ${age}) """ new Sql(datasource).execute query
  45. 45. Strings and GStrings def name = 'Iván' def age = 36 println "¡Hi ${name}, you are ${age} years old!" def query = """ insert into people (firstName, age) values (${name}, ${age}) """ new Sql(datasource).execute query
  46. 46. Numbers that... System.out.println(2.00 - 1.1); // 0.8999999999999999
  47. 47. System.out.println(2.00 - 1.1); // 0.8999999999999999 Numbers that...
  48. 48. System.out.println(3 / 2); // 1 Numbers that...
  49. 49. System.out.println(3 / 2); // 1 Numbers that...
  50. 50. BigDecimal by default! assert 2.0 - 1.1 == 0.9 assert 3 / 2 == 1.5
  51. 51. Equals and == state != null && state.equals(State.COMPLETED);
  52. 52. state == State.COMPLETED Equals and == state != null && state.equals(State.COMPLETED);
  53. 53. Lists def list = ['a', 'b', 'c'] list << 'd' // list.add(“d”) assert list.contains('d') assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D'] assert list.findAll { it.startsWith 'a' }.size() == 1
  54. 54. def list = ['a', 'b', 'c'] list << 'd' // list.add(“d”) assert list.contains('d') assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D'] assert list.findAll { it.startsWith 'a' }.size() == 1 Lists
  55. 55. def list = ['a', 'b', 'c'] list << 'd' // list.add(“d”) assert list.contains('d') assert list.collect { it.toUpperCase() } == ['A', 'B', 'C', 'D'] Lists
  56. 56. Maps def map = [name: 'Iván', age: 36] assert map.name == 'Iván' map.childs = ['Judith', 'Adriana'] assert map['childs'].contains('Adriana')
  57. 57. Maps def map = [name: 'Iván', age: 36] assert map.name == 'Iván' map.childs = ['Judith', 'Adriana'] assert map['childs'].contains('Adriana')
  58. 58. Ranges def range = 'a'..'z' assert range.contains('i') assert range.contains('z') def exclusive = 1..<10 assert !exclusive.contains(10) def inverse = 10..1 assert inverse[0] == 10 assert inverse[-1] == 1
  59. 59. def range = 'a'..'z' assert range.contains('i') assert range.contains('z') def exclusive = 1..<10 assert !exclusive.contains(10) def inverse = 10..1 assert inverse[0] == 10 assert inverse[-1] == 1 Ranges
  60. 60. Ranges def range = 'a'..'z' assert range.contains('i') assert range.contains('z') def exclusive = 1..<10 assert !exclusive.contains(10) def inverse = 10..1 assert inverse[0] == 10 assert inverse[-1] == 1
  61. 61. Power asserts assert (2 + 7) * 5 != (2 * 5) + (7 * 5) (2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35
  62. 62. Power asserts assert (2 + 7) * 5 != (2 * 5) + (7 * 5) (2 + 7) * 5 != (2 * 5) + (7 * 5) | | | | | | 9 45 false 10 45 35
  63. 63. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  64. 64. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  65. 65. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  66. 66. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  67. 67. Power asserts def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]]
  68. 68. def info = [ name: 'Iván', age: 36, childs: [ [name: 'Judith', age: 8], [name: 'Adriana', age: 5] ] ] assert info.childs.name.first() == 'Adriana' info.childs.name.first() == 'Adriana' | | | | | | | | Judith false | | | 6 differences (14% similarity) | | | (Ju)d(-)i(th-) | | | (A-)d(r)i(ana) | | [Judith, Adriana] | [[name:Judith, age:8], [name:Adriana, age:5]] [name:Iván, age:36, childs:[[name:Judith, age:8], [name:Adriana, age:5]]] Power asserts
  69. 69. Groovy truth assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  70. 70. Groovy truth false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  71. 71. Groovy truth assert new Object() assert "string" assert 'string' assert [1, 2] assert [a: 1] assert 1 false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  72. 72. Groovy truth assert new Object() assert "string" assert 'string' assert [1, 2] assert [a: 1] assert 1 true false assert !( null ) assert !( "" ) assert !( '' ) assert !( [] ) assert !( [:] ) assert !( 0 )
  73. 73. Elvis List result = (names != null && names.size() > 0) ? names : Collections.emptyList();
  74. 74. Elvis def result = names ? names : [] List result = (names != null && names.size() > 0) ? names : Collections.emptyList();
  75. 75. Elvis def result = names ? names : [] def result = names ?: [] List result = (names != null && names.size() > 0) ? names : Collections.emptyList();
  76. 76. Safe navigation if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } }
  77. 77. Safe navigation if (order != null) { if (order.getCustomer() != null) { if (order.getCustomer().getAddress() != null) { System.out.println(order.getCustomer().getAddress()); } } } println order?.customer?.address
  78. 78. Closures def multiplier = { a, b -> a * b } assert multiplier(2, 3) == 6 assert multiplier.call(2, 3) == 6 assert multiplier('=', 8) == '========' def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplicador = { int a, int b -> a * b }
  79. 79. def sumador = { ... numbers -> numbers.sum() } assert sumador(1, 2, 3) == 6 assert sumador('a', 'b', 'c') == 'abc' def multiplier = { int a, int b -> a * b } Closures def multiplier = { a, b -> a * b } assert multiplier(2, 3) == 6 assert multiplier.call(2, 3) == 6 assert multiplier('=', 8) == '========'
  80. 80. def adder = { ... numbers -> numbers.sum() } assert adder(1, 2, 3) == 6 assert adder('a', 'b', 'c') == 'abc' Closures def multiplier = { a, b -> a * b } assert multiplier(2, 3) == 6 assert multiplier.call(2, 3) == 6 assert multiplier('=', 8) == '========' def multiplier = { int a, int b -> a * b }
  81. 81. Groovy Closures and Java 8 Lambdas import static java.util.Arrays.asList; public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); } }
  82. 82. import static java.util.Arrays.asList; public class JavaLambdas { public static void main(String[] args) { asList(1, 2, 3).stream() .map(i -> i * 2) .filter(i -> i > 3) .findFirst() .orElseThrow(IllegalArgumentException::new); } } [1, 2, 3].stream() .map { i -> i * 2 } .filter { i -> i > 3 } .findFirst() .orElseThrow(IllegalArgumentException.&newInstance) Groovy Closures and Java 8 Lambdas
  83. 83. Json builder { "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "JavaCro", "SpringOne 2GX", "Greach" ] } } import groovy.json.JsonBuilder def builder = new JsonBuilder() builder. speaker { firstName 'Iván' lastName 'López' address( city: 'Madrid', country: 'España', zip: 12345, ) conferences( 'T3chFest', 'Codemotion', 'Greach' ) } println builder.toPrettyString()
  84. 84. Json builder import groovy.json.JsonBuilder def builder = new JsonBuilder() builder. speaker { firstName 'Iván' lastName 'López' address( city: 'Madrid', country: 'España', zip: 12345, ) conferences( 'JavaCro', 'SpringOne 2GX', 'Greach' ) } println builder.toPrettyString() { "speaker": { "firstName": "Iván", "lastName": "López", "address": { "city": "Madrid", "country": "España", "zip": 12345 }, "conferences": [ "JavaCro", "SpringOne 2GX", "Greach" ] } }
  85. 85. Parse XML and Json in Java
  86. 86. Json parser wind: { speed: 2.6, deg: 170 }, clouds: { all: 20 }, dt: 1460728800, sys: { type: 3, id: 5456, message: 0.0028, country: "HR", sunrise: 1460693949, sunset: 1460742728 }, id: 3191518, name: "Rovinj", cod: 200 } http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=... { coord: { lon: 13.64, lat: 45.08 }, weather: [ { id: 801, main: "Clouds", description: "few clouds", icon: "02d" } ], base: "cmc stations", main: { temp: 19.06, pressure: 1014, humidity: 55, temp_min: 18, temp_max: 20 },
  87. 87. Json parser wind: { speed: 2.6, deg: 170 }, clouds: { all: 20 }, dt: 1460728800, sys: { type: 3, id: 5456, message: 0.0028, country: "HR", sunrise: 1460693949, sunset: 1460742728 }, id: 3191518, name: "Rovinj", cod: 200 } http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=... { coord: { lon: 13.64, lat: 45.08 }, weather: [ { id: 801, main: "Clouds", description: "few clouds", icon: "02d" } ], base: "cmc stations", main: { temp: 19.06, pressure: 1014, humidity: 55, temp_min: 18, temp_max: 20 },
  88. 88. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Leganes&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Tiempo en ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Tiempo en Leganes (ES): few clouds. Temp: 8.84 ºC { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  89. 89. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  90. 90. import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC Json parser { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  91. 91. Json parser import groovy.json.JsonSlurper def url = "http://api.openweathermap.org/data/2.5/weather? units=metric&q=Rovinj&appid=...".toURL() def response = new JsonSlurper().parse(url) String weather = response.weather.collect { it.description }.join(', ') String country = response.sys.country String temp = response.main.temp String city = response.name println "Weather in ${city} (${country}): ${weather}. Temp: ${temp} ºC" // Weather in Rovinj (HR): few clouds. Temp: 19.06 ºC { weather: [ { description: "few clouds", } ], main: { temp: 19.06 }, sys: { country: "HR", }, name: "Rovinj", }
  92. 92. Read text file static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8"); } public static void main(String[] args) { File file = new File("foo"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); } }
  93. 93. static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8"); } public static void main(String[] args) { File file = new File("foo"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); } } String content = new File('foo').text Read text file
  94. 94. static String readFile(File file) throws IOException { byte[] bytes = Files.readAllBytes(file.toPath()); return new String(bytes, "UTF-8"); } public static void main(String[] args) { File file = new File("foo.txt"); try { String content = readFile(file); System.out.println(content); } catch (IOException e) { e.printStackTrace(); } } String content = new File('foo').text Read text file
  95. 95. Read the content of an URL import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
  96. 96. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } println 'http://www.google.com'.toURL().text Read the content of an URL
  97. 97. import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; public class GetURLContent { public static void main(String[] args) { try { URL url = new URL("http://www.google.com"); URLConnection conn = url.openConnection(); BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream())); String inputLine; while ((inputLine = br.readLine()) != null) { System.out.println(inputLine); } br.close(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } println 'http://www.google.com'.toURL().text Read the content of an URL
  98. 98. ➢ Groovy JDK ➢ Adds new types and methods ➢ http://www.groovy-lang.org/gdk.html GDK
  99. 99. 5. I want more!
  100. 100. DSLs: Domain Specific Languages def mailer = new Mailer() mailer.setTo('admin@example.com', 'user@example.com') mailer.setSubject('Urgent!') mailer.setBody('Bla, bla, bla') mailer.setHeaders(spam: 'no', important: true)
  101. 101. DSLs: Domain Specific Languages def mailer = new Mailer() mailer.setTo('admin@example.com', 'user@example.com') mailer.setSubject('Urgent!') mailer.setBody('Bla, bla, bla') mailer.setHeaders(spam: 'no', important: true) def mailer = new Mailer() .setTo('admin@example.com', 'user@example.com') .setSubject('Urgent!') .setBody('Bla, bla, bla') .setHeaders(spam: 'no', important: true)
  102. 102. DSLs: Domain Specific Languages mail { to 'admin@example.com', 'user@example.com' subject 'Urgent!' body 'Bla, bla, bla' headers spam: 'no', important: true } class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" } } void mail(@DelegatesTo(MailComposer) Closure composer) { // Same as: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl() }
  103. 103. DSLs: Domain Specific Languages mail { to 'admin@example.com', 'user@example.com' subject 'Urgent!' body 'Bla, bla, bla' headers spam: 'no', important: true } class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" } } void mail(@DelegatesTo(MailComposer) Closure composer) { // Same as: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl() }
  104. 104. DSLs: Domain Specific Languages mail { to 'admin@example.com', 'user@example.com' subject 'Urgent!' body 'Bla, bla, bla' headers spam: 'no', important: true } class MailComposer { void to(String... addresses) { println "to: $addresses"} void subject(String subject) { println "subject: $subject" } void body(String body) { println "body: $body" } void headers(Map headers) { println "headers: $headers" } } void mail(@DelegatesTo(MailComposer) Closure composer) { // Same as: // new MailComposer().with(composer) Closure cl = composer.clone() cl.delegate = new MailComposer() cl.resolveStrategy = Closure.DELEGATE_FIRST cl() }
  105. 105. ➢ +50 transformations out-of-the-box ➢ @ToString, @EqualsAndHashCode, @InheritConstructors, @Sortable, @Delegate, @Immutable, @CompileStatic,... AST Transformations
  106. 106. @EqualsAndHashCode public class User extends java.lang.Object { private String name private Integer age public int hashCode() { java.lang.Object _result = org.codehaus.groovy.util.HashCodeHelper.initHash() if (!(this.getName().is(this))) { _result = HashCodeHelper.updateHash(_result, this.getName()) } if (!(this.getAge().is(this))) { _result = HashCodeHelper.updateHash(_result, this.getAge()) } return _result } public boolean canEqual(Object other) { return other instanceof User } public boolean equals(Object other) { if ( other == null) { return false } if (this.is(other)) { return true } if (!( other instanceof User)) { return false } User otherTyped = (( other ) as User) if (!(otherTyped.canEqual( this ))) { return false } if (!(this.getName() == otherTyped.getName())) { return false } if (!(this.getAge() == otherTyped.getAge())) { return false } return true } }
  107. 107. @EqualsAndHashCode @groovy.transform.EqualsAndHashCode class User { String name Integer age }
  108. 108. Thank you! Questions? @ilopmar lopez.ivan@gmail.com https://github.com/ilopmar Iván López http://bit.ly/javacro-groovy

×