Groovy collection comparison is easy

One thing I found myself doing more than I wanted with java was collection comparison. Many times, you might have a large list of all available items, and a smaller list of selected items. Commonly, you might want to find all the items that exist in the large collection, but have not been ’selected’ in the smaller collection. Invariably in java, this means nested loops.

Not so much with groovy.

List subtraction
def smallList = [1,3,5]
def bigList = [1,1,1,2,3,4,4,4,5,6,7,7,8,9]

def result = bigList - smallList
println result.class
println result

The result is:

class java.util.ArrayList
[2, 4, 4, 4, 6, 7, 7, 8, 9]

Groovy correctly made the assumption that I was making a List in my snippet above. And it removed any element within the first list where equals() was true for an element in the first list. That means it took away three 1’s and one 3. Keep in mind the original collections are untouched.

But what if I want to compare a List and a Set?

Set/List addition
Set mySet = [1,3,5]

List myList = [0,1,2,3,4,0,1,2,3,4,5,6,7,8,9]

def addition = myList + mySet
println addition.class
println addition

addition = mySet + myList
println addition.class
println addition

Now we’re adding a List and a Set together, and the result is different depending on which is the first operand:

class java.util.ArrayList
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 3, 5]
class java.util.HashSet
[2, 4, 9, 8, 6, 1, 3, 7, 5, 0]

If the List is the first operand, groovy assumes you want to treat the following operand as a List as well, and it just tacks the values onto the end. But when the Set is first, groovy first converts the second argument into a Set as well before doing its addition. This removes all but unique elements from it before performing the addition.

Set/List subtraction
Set mySet = [1,3,5]

List myList = [0,1,2,3,4,0,1,2,3,4,5,6,7,8,9]

def subtraction = myList - mySet
println subtraction.class
println subtraction

subtraction = mySet - myList
println subtraction.class
println subtraction

We should again see the automatic type conversion as in the above examples depending on which type is the first operand. In the results below, you can see that all elements within the set were removed from the list (there are no 1’s, 3’s, or 5’s). The second subtraction results in 0 elements, because the List (which is converted to a Set) being subtracted contains 1, 3, and 5, so all are removed from the original Set.

class java.util.ArrayList
[0, 2, 4, 0, 2, 4, 6, 7, 8, 9]
class java.util.HashSet
[]

Good stuff. This is just another example of how groovy does away with a lot of the annoying things you have to do with java.

When groovy comes across an operator like “-” or “+”, it looks for a method on the left operand called either “plus” or “minus”. So in the above examples, mySet - myList is the same as mySet.minus(myList).
This entry was posted in uncategorized and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

6 Comments

  1. Posted March 27, 2008 at 12:26 am | Permalink

    Nice.

  2. Dan Lewis
    Posted March 27, 2008 at 1:44 pm | Permalink

    If only there was a way to subtract a collection from another using plain old Java. :P

  3. Posted March 27, 2008 at 1:56 pm | Permalink

    In all fairness, yes, you can do similar things with the Apache collections package. But why would you want to go looking for tons of third party jars to add to your project when all you really need is groovy-all.jar, baby.

    Also, I’d like to see you try to use the ‘+’ and ‘-’ on collections using any third party java jar.

  4. ahmetaa
    Posted March 27, 2008 at 10:12 pm | Permalink

    Just write a simple helper. I guarantee that it will be 20 times faster than Groovy.

  5. Posted March 28, 2008 at 6:36 am | Permalink

    Unless you are doing some math in your app (and in all my J2EE experience, you hardly ever have much of that), the most time-consuming part of a J2EE application is communicating with another service. Whether it is calling a web service or a round-trip to the database, that is where your time costs comes into play.

    Groovy is slow with math, but that is such a small part of today’s applications (it is all abstracted to much lower levels). I think you would be surprised by how little you would notice the speed difference between groovy and java in a case like this.

    You might write a helper that takes you 6 hours to write (if you test it properly, possibly more), but you could have written your code in 10 seconds if you were using groovy, and you would have 100% confidence that it would work properly the first time.

    Developer velocity is more important than program velocity.
  6. Posted April 9, 2008 at 12:08 pm | Permalink

    Regarding performance, I wrote a simple helper. Java was about 6 times faster, quite a bit less than 20 times faster. And that’s not bad when you consider that quite a few Groovy performance improvements are in the pipeline.

    http://jimloverde.blogspot.com/2008/04/simple-java-vs-groovy-perfomance.html

2 Trackbacks

  1. By NVISIA - Simple Java vs Groovy Perfomance Comparison on September 15, 2008 at 10:30 am

    [...] Java vs Groovy Perfomance Comparison I recently read a post about doing comparisons with Groovy collections, and there was a snide comment that caught my eye: Just write a simple helper. I guarantee that it [...]

  2. By NVISIA - Simple Java vs Groovy Perfomance Comparison on September 30, 2008 at 12:01 pm

    [...] recently read a post about doing comparisons with Groovy collections, and there was a snide comment that caught my eye: Just write a simple helper. I guarantee that it [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*
Check out the latest GroovyMag to see an interview with me about the 1.1 release of GrailsUI: