title: Multi criteria sorting of a list of objects with Guava Ordering
body: <p>I have a class WHICH CANNOT implement comparable, but needs to be sorted based on 2 fields. How can I achieve this with Guava?</p>
  
  <p>Let's say the class is:</p>
  
  <pre><code>class X {
    String stringValue;
    java.util.Date dateValue;
  } 
  </code></pre>
  
  <p>And I have a list of these:</p>
  
  <pre><code>List&lt;X&gt; lotsOfX;
  </code></pre>
  
  <p>I want to sort them based on the value field first and then based on dateValue descending within each 'group' of 'value' fields.</p>
  
  <p>What I have been doing so far is:</p>
  
  <pre><code>List&lt;X&gt; sortedList = ImmutableList.copyOf(Ordering.natural().onResultOf(dateValueSortFunction).reverse().sortedCopy(lotsOfX));
  sortedList = ImmutableList.copyOf(Ordering.natural().onResultOf(stringValueSortFunction).sortedCopy(sortedList));
  </code></pre>
  
  <p>The functions are defined as:</p>
  
  <pre><code>public class DateValueSortFunction&lt;X&gt; implements Function&lt;X, Long&gt; {
  
      @Override
        public Long apply(X input) {
          return input.getDateValue().getTime();  //returns millis time
        }
  }
  </code></pre>
  
  <p>And:</p>
  
  <pre><code>public class StringValueSortFunction&lt;X&gt; implements Function&lt;X, Integer&gt; {
  
        @Override
          public Integer apply(X input) {
            if(input.getStringValue().equalsIgnoreCase("Something"))
              return 0;
            else if(input.getStringValue().equalsIgnoreCase("Something else"))
              return 1;
            else
              return 2;
          }
  }
  </code></pre>
  
  <p>Expected output in <code>sortedList</code> is:</p>
  
  <pre><code>Something   03/18/2013
  Something   03/17/2013
  Something else  03/20/2013
  Something else  03/19/2013
  ....
  </code></pre>
  
  <p>My approach works but is obviously inefficient for traversing the list twice. Is there a better way of doing this?</p>
  
  <p>I am using this in a GWT app. Implementing comparable is not an option.</p>