Understanding Groovy 2.0 withLazyDefault and withEagerDefault methods

17 / Sep / 2012 by Divya Setia 0 comments

Sometimes there is need to get some default value in place of null values from a list, that was the reason I came across: withLazyDefault and withEagerDefault methods.

My use case consisted of a list of user names with possibility of null elements, hence wherever the element was null, I wanted to return “unknown”. Although there was other ways of doing the same, but most cleaner way was using withLazyDefault.

These methods are also useful when a list is accessed for a index which doesnot exist i.e. avoiding index out of bound exception. And for map, these methods are useful when map is accessed for a key, whose entry(key-value pair) does not exist.

Lets start with withLazyDefault method. We can also use withDefault instead of withLazyDefault because withDefault method calls withLazyDefault internally.

List<String> languages = ["C","C++",null, "Flex","VB","Java"].withDefault{"Groovy"}

println languages.get(2)

//Output : Groovy,  (even though at index 2, value is null)

As the value at index 2 was null, but because of default value set at initialization time, langauges.get(2) returned “Groovy” as value.

Now, If a list is accessed for a index (lets say mth index) greater than languages.size()-1 (lets say nth index, list’s actual size), and if default value is set using withDefault(withLazyDefault), then list grows to the size (m+1). The gap in between is filled with null values, although access to list using any index in gap will return default value.

e.g.

 List<String> languages = ["C","C++",null, "Flex","VB","Java"].withDefault{"Groovy"}

println languages.size()
//Output : 6

println languages.get(10)
//Output : Groovy

println languages.size()
//Output : 11

println languages
// [C, C++, null, Flex, VB, Java, null, null, null, null, Groovy]

println languages.get(8)
// Output : Groovy

As you will see, no indexOutOfBoundException will occur and size will grow to the specified index.

Usage with Map:

Map<String,Integer> languages = ["C":1,"C++":3, "Flex":5,"VB":4,"Java":5].withDefault{10}

println languages.size()
//Output : 5

println languages.get("Groovy")
//Output : 10

println languages.get("COBOL")
//Output : 10

println languages.size()
//Output : 7

println languages
//Output : [C:1, C++:3, Flex:5, VB:4, Java:5, Groovy:10, COBOL:10]

A new entry gets added in the map for the key whose entry (key-value pair) does not exist in Map with default value.

The only difference between withLazyDefault and withEagerDefault is that the gap between actual list and new list will be populated with default value in case of withEagerDefault instead of null values as in case of withLazyDefault method.

In case of withLazyDefault:

List<String> languages = ["C","C++",null, "Flex","VB","Java"].withLazyDefault{"Groovy"}

println languages.get(10)
// Output : Groovy

println languages
//Output: [C, C++, null, Flex, VB, Java, null, null, null, null, Groovy]

In case of withEagerDefault:

List<String> languageList = ["C","C++",null, "Flex","VB","Java"].withEagerDefault{"Groovy"}

println languageList.get(10)
//Output : Groovy

println languageList // Output: [C, C++, null, Flex, VB, Java, Groovy, Groovy, Groovy, Groovy, Groovy]

Hope it would help!!!

Divya Setia
divya@intelligrape.com
https://twitter.com/divs157

FOUND THIS USEFUL? SHARE IT

Leave a comment -