Search

March 11, 2020

Groovy Goodness: Getting Parts Of A String Enclosed By Strings

Groovy 3 adds the takeBetween method to the String class. With this method we can get all the characters that are enclosed by string values. We can specify one enclosed string value and then all text between the the first occurrence of the string and the second occurrence is returned. If multiple parts are enclosed by the string values we can also specify which occurrence we want. If the text is enclosed by different string values we can use a variant of takeBetween that takes two string values to indicate the boundaries of the text we want. Also with two different enclosed string values we can use an argument to get the n-th occurrence of the string that is found.
Since Groovy 3 we can also use takeBefore and takeAfter to get the string before or after a given string value. All three methods will return an empty string if no text can be found.

In the following example we use the takeBefore, takeAfter and takeBetween methods with different arguments:

def text = 'Just saying: "Groovy is gr8!"'

// Return all characters before the first quote.
assert text.takeBefore('"') == 'Just saying: '
// Return everything after the colon.
assert text.takeAfter(': ') == '"Groovy is gr8!"'
// Return everything between two quotes.
assert text.takeBetween('"') == 'Groovy is gr8!'
// Return text between is and !.
assert text.takeBetween('is', '!') == ' gr8'

// When no value can be found
// an empty string is returned.
assert text.takeBefore('?') == ''
assert text.takeAfter('Java') == ''
assert text.takeBetween('-') == ''
assert text.takeBetween('[', '/') == ''

def sample = 'JVM languages are "Groovy", "Clojure", "Java".'

assert sample.takeBetween('"') == 'Groovy'
// We can also specify which occurrence we 
// want for a text between same strings.
assert sample.takeBetween('"', 0) == 'Groovy'
assert sample.takeBetween('"', 1) == 'Clojure'
assert sample.takeBetween('"', 2) == 'Java'


def users = "Users: [mrhaki], [hubert]"

assert users.takeBetween('[', ']') == 'mrhaki'
// We can also specify which occurrence we 
// want for a text between to strings.
assert users.takeBetween('[', ']', 0) == 'mrhaki'
assert users.takeBetween('[', ']', 1) == 'hubert'
// When no occurrence an empty string is returned.
assert users.takeBetween('[', ']', 2) == ''

Written with Groovy 3.0.2.

March 10, 2020

Groovy Goodness: Taking Or Dropping Number Of Characters From A String

Groovy adds a lot of methods to the Java String class. For example we can use the take method to get a certain number of characters from the start of a string value. With the drop method we remove a given number of characters from the start of the string. In Groovy 3 we can now also take and drop a certain number of characters from the end of a string using the methods takeRight and dropRight.

In the following example we see how we can use the methods:

def s = "Groovy rocks!"

// Drop first 7 characters.
assert s.drop(7) == "rocks!"

// Drop last 7 characters.
assert s.dropRight(7) == "Groovy"


// Take first 6 characters.
assert s.take(6) == "Groovy"

// Take last 6 characters.
assert s.takeRight(6) == "rocks!"

Written with Groovy 3.0.2.

March 8, 2020

Groovy Goodness: Check Object Instances Are The Same With === Operator

Groovy has used the == operator to check if objects are equal for a long time. To test if object instances are the same we must use the is method. Groovy 3 adds a new operator for the is method and that is the === operator. And to negate the result of the is method we can use the !== operator.

In the following example we use the === and !== operator to check if objects refer to the same instance or not:

def answer = new Integer(42)
def anotherAnswer = new Integer(42)
def meaningOfLife = answer

// Equals is true for answer and anotherAnswer
assert answer == anotherAnswer

// But they don't refer to the same instance.
assert answer !== anotherAnswer

// The variables meaningOfLife and answer
// do refer to the same object instance.
assert answer === meaningOfLife

Written with Groovy 3.0.2.

March 4, 2020

Groovy Goodness: Using !instanceof Operator

Groovy 3 adds the !instanceof operator to check if an object is not an instance of a type. This is a shorthand for using instanceof and then negate the result. It shows how little changes can make code easier to read.

In the following example we use the old way to check if object is not an instance of a type and the new !instanceof operator:

// Check using !(obj instanceof type) 
// if object is not an instance of type.
assert !("Groovy is awesome!" instanceof Number)

// Since Groovy 3 we can use !instanceof to check
// if object is not an instance of a type.
assert 42 !instanceof String

Written with Groovy 3.0.1.

March 3, 2020

Groovy Goodness: Safe Index Based Access For Lists, Arrays and Maps

Groovy 3 adds the feature of safe index based access for lists, arrays and maps. This means we can use ?[index] to get or a set a value on a list or array without getting a NullPointerException when the list or array is not initialised. With maps we can use ?[key] for getting a value or set a value and when the map object is not initialised we don't get a NullPointerException.

In the following example we see several examples of setting or getting values using indices or keys:

def list = null

// Accessing null list or array 
// using index based access, 
// will throw NullPointerException when
// collection is null.
try {
    list[0]
} catch (NullPointerException npe) {
    assert npe
}

// Using ?[...] will not throw NullPointerException.
assert list?[0] == null

// Assignment are ignored when list is null.
list?[1] = 42
assert list?[1] == null

// When collection is not null we simply
// get the default behaviour for index based
// access of elements.
def values = ["Groovy", "rocks"]
assert values?[0] == "Groovy"
values?[2] = '!'
assert values?.join(" ") == "Groovy rocks !"

// We can use ?[key] for maps as well.
def info = null
assert info?['address'] == null
info?['address'] = 'unknown'
assert info?['address'] == null

def user = [alias: 'mrhaki', loves: 'Groovy']
assert user?['alias'] == 'mrhaki'
user?['country'] = 'The Netherlands'
assert user?['country'] == 'The Netherlands'
assert user?['age'] == null

Written with Groovy 3.0.1.

February 28, 2020

Java Joy: Turn A Pattern Into A Predicate

This week at work a colleague showed a nice feature of the Pattern class in Java: we can easily turn a Pattern into a Predicate with the asPredicate and asMatchPredicate methods. The asPredicate method return a predicate for testing if the pattern can be found given string. And the asMatchPredicate return a predicate for testing if the pattern matches a given string.

In the following example code we use both methods to create predicates:

package mrhaki;

import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class PatternPredicate {

    public static void main(String[] args) {
        // Sample pattern.
        var pattern = Pattern.compile("J");

        // asPredicate returns a predicate to test if 
        // the pattern can be found in the given string.
        assert pattern.asPredicate().test("Java");
        assert !pattern.asPredicate().test("Groovy");

        // asMatchPredicate returns a predicate to test if
        // the pattern completely matches the given string.
        assert pattern.asMatchPredicate().test("J");
        assert !pattern.asMatchPredicate().test("Java");


        // Using the asPredicate and asMatchPredicate is very
        // useful with the streams API.
        var languagesWithJ = Stream.of("Java", "Groovy", "Clojure", "JRuby", "JPython")
                                   .filter(pattern.asPredicate())
                                   .collect(Collectors.toList());

        assert languagesWithJ.size() == 3;
        assert languagesWithJ.equals(List.of("Java", "JRuby", "JPython"));

        var startsWith_J_EndsWith_y = Pattern.compile("^J\\w+y$").asMatchPredicate();
        var languagesWithJy = Stream.of("Java", "Groovy", "Clojure", "JRuby", "JPython")
                                    .filter(startsWith_J_EndsWith_y)
                                    .collect(Collectors.toList());

        assert languagesWithJy.size() == 1;
        assert languagesWithJy.equals(List.of("JRuby"));
    }
}

Written with Java 13.

February 27, 2020

Groovy Goodness: The Elvis Assignment Operator

Groovy 3 adds a new operator to the language: elvis assignment operator (?=). This operator is a shorthand for an assignment where we want to assign a value to a variable or property if the variable or property is null or false (following Groovy truth). If the value of the variable or property is not null or false (again apply Groovy truth rules), the value stays the same.

In the following example code we use the elvis assignment operator:

// First an example using the elvis operator.
a = null
a = a ?: 100

assert a == 100

// Now we can shorten the assignment using the 
// elvis assignment operator.
a = null
a ?= 100

assert a == 100

b = 200
b ?= 100

assert b == 200

// The elvis assignment operator can also 
// be useful in maps to set default values.
def m = [a: 1, b: 2]
m.a = 100
m.b ?= 200
m.c ?= 300

assert m.a == 100
assert m.b == 2
assert m.c == 300

// Also to set default values for properties
// in an object. Especially if we cannot
// change the class to set a default value.
// In our example we have the source of the
// Email class and we could set default values
// in the class definition, but if the class
// is not under our control we can use the
// elvis assignment operator to set default
// values easily.
class Email {
    String to, from, subject, body
}

def mail = new Email(to: 'test@mrhaki.com', 
                     subject: 'Sample', 
                     body: 'Trying Elvis assignment.')
mail.subject ?= 'Mail has no subject'
mail.from ?= 'no-reply@mrhaki.com'

assert mail.to == 'test@mrhaki.com'
assert mail.from == 'no-reply@mrhaki.com'
assert mail.subject == 'Sample'
assert mail.body == 'Trying Elvis assignment.'

Written with Groovy 3.0.1.

February 23, 2020

Groovy Goodness: Lambda Default Parameter Value

Groovy 3 adds support for Java's lambda syntax expressions. This way we can write code in Groovy using lambda expressions just like in Java. But Groovy adds an additional feature and that is default parameter values for lambda expressions.

In the following example we use a default parameter value for a lambda expression.

// Groovy 3 supports Java's lambda syntax expressions.
def inc = n -> n + 1

assert inc(1) == 2


// But also adds default parameter values.
def multiplyBy = (n, factor = 2) -> n * factor

assert multiplyBy(1) == 2
assert multiplyBy(1, 10) == 10

Written with Groovy 3.0.1.

February 21, 2020

Groovy Goodness: Check Item Is Not In A Collection With !in

Groovy contains lots of little gems that just make live easier and our code more expressive. Groovy 3 doesn't disappoint by adding some nice syntax additions. For example we can now use !in to check if an item is not in a collection, opposed to in that checks if an item is in a collection.

In the following example we use !in:

def list = ['Groovy', 3, 'is', 'awesome', '!']

// New Groovy 3 syntax to check item 
// is NOT in a collection.
assert 'Java' !in list

// Old syntax.
assert !('Java' in list)

// Just to show in still works.
assert 'Groovy' in list

Written with Groovy 3.0.1.

February 19, 2020

Groovy Goodness: Shuffle List or Array

In Java we can use Collections.shuffle method to randomly reorder items in a list. Groovy 3.0.0 adds the shuffle and shuffled methods to a List or array directly. The implementation delegates to Collections.shuffle. The shuffle method will reorder the original list, so there is a side effect using this method. Or we can use the shuffled method that will return a copy of the original list where the items are randomly ordered.

In the next example we use both methods to randomly order lists:

def signs = (2..10) + ['J', 'Q', 'K', 'A']
def symbols = ['♣', '♦', '♥', '♠']

// Create list as [♣2, ♦2, ♥2, ♠2, ..., ♣A, ♦A, ♥A, ♠A] 
def cards = [symbols, signs].combinations().collect { it.join() }

// Store original cards list.
def deck = cards.asImmutable()

// We should have 52 cards.
assert cards.size() == 52

// Let's shuffle the cards.
// Notice this will change the cards list.
cards.shuffle()
 
assert cards.every { card -> deck.contains(card) }

println cards.take(5) // Possible output: [♣6, ♠A,  ♥Q, ♦Q, ♠5]

// We can use our own Random object for shuffling.
cards.shuffle(new Random(42))

assert cards.every { card -> deck.contains(card) }

println cards.take(5)  // Possible output: [♦5, ♦2, ♦3, ♣7, ♦J]


// Store first 5 cards.
def hand = cards.take(5)

// Using shuffled we get a new list 
// with items in random order. 
// The original list is not changed.
def shuffledCards = cards.shuffled()

assert shuffledCards.size() == cards.size()
assert shuffledCards.every { card -> cards.contains(card) }

// Original list has not changed.
assert hand == cards.take(5)

println shuffledCards.take(5) // Possible output: [♣4, ♠2, ♠6, ♥Q, ♦4]

// We can pass our own Random object.
def randomizer = new Random(42)
def randomCards = cards.shuffled(randomizer)

assert randomCards.size() == cards.size()
assert randomCards.every { card -> cards.contains(card) }

println randomCards.take(5) // Possible output: [♥5, ♠6, ♠8, ♣3, ♠4]

Written with Groovy 3.0.0.