Since most readers are already familiar with Java, it would be helpful to compare common Java idioms with the Groovy equivalent.
Default Method Values
Note
Using the "def" keyword in this way defines a method with return type of java.lang.Object.
Equals, HashCode, and More
Groovy has many annotations in the "groovy.transform" package that implement AST transformations (Abstract Syntax Tree transformations). In other words, they simplify life by adding commonly written code (often called “boilerplate”) to the byte-code of your class for you at compilation time when you use them to annotate your class.
One of the tedious tasks you must often do in Java is create an equals and a hashCode method for a class. For this purpose, Groovy added the @EqualsAndHashCode annotation. Simply add it to the top of your class (right before the word class) and you’re done.
Likewise, you often want to create a constructor for all of the fields of a class. For this, Groovy has @TupleConstructor . It uses the order of the definitions of your fields to define a constructor with parameters for initializing those fields. Just add it right before your class definition.
There’s also the @ToString annotation you can add before your class definition for automatically creating a toString() method for your class. You can also configure it to include or exclude certain fields.
Exercise
Create your own class with multiple properties using these annotations.
Regex Pattern Matching
Groovy greatly simplifies using a pattern to match text using regex (regular expressions).
Where in Java you must use the java.util.regex.Pattern class, create an instance, and then create a Matcher; in Groovy this can all be simplified to one line.
This allows you to find regular expressions inside strings and to get sub-groups from a regex.
Exercise
Create a better regex for validating e-mail in Groovy.
Missing Java Syntax
Due to the nature of Groovy’s syntax and some additions to Java’s syntax over the years, Groovy was “missing” a few things before version 3.0. However, there are other ways to do the same things.
Optional Semicolon
Since the semicolon is optional in Groovy, this can sometimes cause line-ending confusion when you’re used to Java. Usually this is not a problem, but when calling multiple methods in a row (using a fluent API, for example), this can cause problems. In this case, you need to end each line with a non-closed operator, such as a dot.
Optional Parenthesis Sometimes
Where Are Generics?
This would cause the compilation error "[Static type checking] - Incompatible generic argument types. Cannot assign java.util.List <java.lang.Number> to: java.util.List <Integer>". Since 3.1415 becomes a java.math.BigDecimal in Groovy, the generic type of the list is automatically determined to be java.lang.Number.
Groovy Numbers
This discussion leads us to decimal numbers, which use BigDecimal by default in Groovy. This allows you to do math without rounding errors.
Exercise
Try multiplying different number types and determining the class of the result.
Boolean-Resolution
Since Groovy is very similar to Java, but not Java, it’s easy to get confused by the differences. A couple of the areas of confusion are boolean-resolution (also called “Groovy truth”) and the Map syntax sugar.
Tip
This is sometimes referred to as “Groovy truth”.
Map Syntax
Groovy syntax sugar for maps allows you use string keys directly, which is often very helpful. However, this can cause confusion when attempting to get the class-type of a map using Groovy’s property-accessor syntax sugar (.class refers to the key-value, not getClass()). So you should use the getClass() method directly.
Without the parentheses, foo would resolve to the String "foo". With the parentheses, the String "key" will be used as the key mapped to the value 2.
Summary
You can provide default method values.
Various annotations that simplify life in the groovy.transform package.
How regular expressions are built into Groovy.
Different ways of defining arrays in Groovy.
How to use unclosed operations when writing a multiline statement.
Groovy uses BigDecimal by default for non-integer numbers.
Groovy truth.
You can use variable keys in the map syntax.