2

I have a class with two date fields say:

class TestData {
    Date activation;
    Date timeStamp;
}

I want to sort the list of the above class on basis of activation date and if they are equal then on basis of timestamp i.e. max(activation) and max(timeStamp).

Code I tried is as follws which only fetch max(activation)

public class CollectionSort {

    public static void main(String[] args) {
        List<TestData> testList = new ArrayList<TestData>();

        Collections.sort(testList, new Comparator<TestData>() {

            @Override
            public int compare(TestData t1, TestData t2) {
                int result = 0;
                if (t1.getActivation().before(t2.getActivation())) {
                        result = 1;
                }
                return result;
            }
        });
        System.out.println("First object is " + testList.get(0));
    }
}

Any help would be greatly appreciated.

Thanks

user698217
  • 23
  • 1
  • 5
  • 2
    Note that if your `Comparator` implementation can never return a negative integer (usually `-1`) then it's almost certainly wrong! Because if `compare(a, b)` returns a positive `int`, then `compare(b, a)` **must** return a negative one! – Joachim Sauer Apr 08 '11 at 08:11
  • 1
    You do not need the casts to TestData or the instanceof test in your compare method. Since generics (Java 5) the casts are done automatically for you behind the scenes, hence the method parameters already being of type TestData. – Russ Hayward Apr 08 '11 at 08:11

2 Answers2

9

This would do it.!

        Collections.sort(yourList, new Comparator<TestData>() {    
            public int compare(TestData o1, TestData o2) {
                int date1Diff = o1.getActivation().compareTo(o2.getActivation());
                return date1Diff == 0 ? 
                        o1.geTimestamp().compareTo(o2.getTimestamp()) :
                        date1Diff;
            }               
        });
Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
jmj
  • 237,923
  • 42
  • 401
  • 438
9

Here's how to do it in Plain Java:

 public int compare(TestData o1, TestData o2) {
    int result = o1.getActivation().compareTo(o2.getActivation()));
    if(result==0) result = o1.getTimeStamp().compareTo(o2.getTimeStamp());
    return result;
 }

Or with Guava (using ComparisonChain):

public int compare(TestData o1, TestData o2) {
    return ComparisonChain.start()
      .compare(o1.getActivation(), o2.getActivation())
      .compare(o1.getTimeStamp(), o2.getTimeStamp())
      .result();
 }

Or with Commons / Lang (using CompareToBuilder):

public int compare(TestData o1, TestData o2) {
    return new CompareToBuilder()
      .append(o1.getActivation(), o2.getActivation())
      .append(o1.getTimeStamp(), o2.getTimeStamp())
      .toComparison();
 }

(All three versions are equivalent, but the plain Java version is the most verbose and hence most error-prone one. All three solutions assume that both o1.getActivation() and o1.getTimestamp() implement Comparable).

Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588