Using Google Guava’s Ordering API

We’ve been playing a bit more with Google’s Guava library – what a great library! The most recent thing we used it for was to sort out the comparators for our domain objects. Here’s how. Using Apache IsisJDO Objectstore, it’s good practice to make your classes implement java.lang.Comparable, and use SortedSet for the collections. You can see this in Isis’ quickstart archetype, where the ToDoItem has a recursive relationship to itself:

public class ToDoItem implements Comparable<ToDoItem> {
    private SortedSet<ToDoItem> dependencies = Sets.newTreeSet();

How best to implement the compareTo method, though? Here’s the original implementation:

    public int compareTo(final ToDoItem other) {
        if (isComplete() && !other.isComplete()) {
            return +1;
        if (!isComplete() && other.isComplete()) {
            return -1;
        if (getDueBy() == null && other.getDueBy() != null) {
            return +1;
        if (getDueBy() != null && other.getDueBy() == null) {
            return -1;
        if (getDueBy() == null && other.getDueBy() == null ||
            getDueBy().equals(this.getDueBy())) {
            return getDescription().compareTo(other.getDescription());
        return getDueBy().compareTo(getDueBy());

Yuk! Basically it says:
* order the not-yet-completed objects before the completed-objects
* where there’s a tie, order by due date (put those without a due by date last)
* where there’s a tie, order by description.

Here’s how to rewrite that using Guava’s Ordering class. First, let’s create some Ordering instances for the scalar types:

public final class Orderings {

    public static final Ordering<Boolean> BOOLEAN_NULLS_LAST = 
    public static final Ordering<LocalDate> LOCAL_DATE_NULLS_LAST = 
    public static final Ordering<String> STRING_NULLS_LAST = 

    private Orderings(){}

Now we can rewrite our ToDoItem‘s compareTo() method in a declarative fashion:

public class ToDoItem implements Comparable {


    public int compareTo(ToDoItem o) {
               .compare(this, o);

    public static Ordering<ToDoItem> ORDERING_BY_COMPLETE = new Ordering<ToDoItem>(){
        public int compare(ToDoItem p, ToDoItem q) {
            return, q.isComplete());

    public static Ordering<ToDoItem> ORDERING_BY_DUE_BY = new Ordering()<ToDoItem>{
        public int compare(ToDoItem p, ToDoItem q) {
            return, q.getDueBy());

    public static Ordering<ToDoItem> ORDERING_BY_DESCRIPTION = new Ordering()<ToDoItem>{
        public int compare(ToDoItem p, ToDoItem q) {
              p.getDescription(), q.getDescription());

Now, admittedly, this hardly warrants all that boilerplate for just a single method in a single class; of course not! But what we have here now is a little algebra that we can use to combine across all the domain classes in our domain model. Other domain classes that use a ToDoItem can order themselves using the ToDoItem‘s natural ordering (accessed from Ordering.natural()), or they can create new orderings using the various ToDoItem.ORDERING_BY_xxx orderings.

Reference: Using Google Guava’s Ordering API from our JCG partner Dan Haywood at the Dan Haywood blog blog.

Related Whitepaper:

Bulletproof Java Code: A Practical Strategy for Developing Functional, Reliable, and Secure Java Code

Use Java? If you do, you know that Java software can be used to drive application logic of Web services or Web applications. Perhaps you use it for desktop applications? Or, embedded devices? Whatever your use of Java code, functional errors are the enemy!

To combat this enemy, your team might already perform functional testing. Even so, you're taking significant risks if you have not yet implemented a comprehensive team-wide quality management strategy. Such a strategy alleviates reliability, security, and performance problems to ensure that your code is free of functionality errors.Read this article to learn about this simple four-step strategy that is proven to make Java code more reliable, more secure, and easier to maintain.

Get it Now!  

Leave a Reply

+ 6 = fifteen

Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.
Do you want to know how to develop your skillset and become a ...
Java Rockstar?

Subscribe to our newsletter to start Rocking right now!

To get you started we give you two of our best selling eBooks for FREE!

Get ready to Rock!
You can download the complementary eBooks using the links below: