Neverending Groovy: map with default values

More and more Groovy openings for me every day!

Just today, I found that there is a way to setup default value for map entry, if absent. In some cases it may be very handy.

For example, I need to prepare a map with words counts. This simple task should be coded simple too, like:

def map = [:]
words.each { word -> map[word]++ }

But it's not working and fails with NPE exception. Why? Because it's hard to increment null.

Although, there is simple way to avoid this problem even using Groovy API:

def map = [:]
words.each { word -> map[word] = map.get('word', 0) + 1

Here 2nd parameter of map.get() method is the default value, returned if there is no value for key 'word'. And now it's working fine!
Still there is another way, and, as for me, it helps to make code clean and safe. Safe because default logic can be used elsewhere we want to use our map object.

def map = [:].withDefault { 0 }
words.each { word -> map[word]++ }

I bet there is a better way and I'm going to find it...

1 comment:

Tim Green said...

Many thanks for posting this. Used this technique in Perl on many occasions and was wondering how to achieve the same in Groovy. Tim