Saturday, 20 February 2010

Google collections ordering and filtering

Recently on my project I faced a task that could be simplified to a following problem:
I have a list of objects of class Foo, which has a field bar which is a String. I get a list of Strings X and the task is:
a) from the set of objects Foo I need to filter out anything for which the bar field is not equal to one of the Strings on the list X
b) the order of objects Foo according to their bar value must match the order of Strings on the list X

Google Collections came to the rescue allowing me to write a nice and concise (and bug-free!) code in a matter of minutes. Here is how it looked like:


import java.util.Collection;
import java.util.List;

import com.google.common.base.Function;
import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Ordering;

public class Bazz {

private final static class Foo {
private String bar;

public String getBar() {
return bar;
}
}

/**
* @param bars
* Reference bar List to define filter and sorting
* @param foos
* List of object that needs to be filtered and sorted
* @return Filtered and sorted Foos
*/
public List filterAndSort(final List bars, final List foos) {

Collection filtered = Collections2.filter(foos, new Predicate() {
public boolean apply(Foo foo) {
return bars.contains(foo.getBar());
}
});
Ordering fooOrdering = Ordering.explicit(bars).onResultOf(new Function() {
public String apply(Foo foo) {
return foo.getBar();
}
});
return fooOrdering.sortedCopy(filtered);
}
}



The only thing I'm currently wondering about is how would it look in a functional language like Scala for which the book is already in the reading queue...