2

Am somewhat confused with Java's compareTo() and Collections.sort() behavior.

I am supposed to sort a column in ascending order using compareTo() & Collections.sort().

My criteria is (if the same number occurs than please sort the next available column).

(1) Document Number (2) Posting Date (3) Transaction Date (4) Transaction Reference Number Comparison

Here's the code (which is executed in a calling method) that implements the Collection.sort() method:

public int compareTo(CreditCardTransactionDetail t) {
   int comparison = 0;

   int documentNumberComparison = this.getDocumentNumber().compareTo(t.getDocumentNumber());
   if (documentNumberComparison != 0) {
       comparison = documentNumberComparison;
   } 
   else {
       int postingDateComparison = this.getTransactionPostingDate().compareTo(t.getTransactionPostingDate());
       if (postingDateComparison != 0) {
           comparison = postingDateComparison;
       } 
       else {
           int transactionDateComparison = this.getTransactionDate().compareTo(t.getTransactionDate());
           if (transactionDateComparison != 0) {
               comparison = transactionDateComparison;
           }
           else {
               int transactionRefNumberComparison = this.getTransactionReferenceNumber().compareTo(t.getTransactionReferenceNumber());
               LOG.info("\n\n\t\ttransactionRefNumberComparison = " + transactionRefNumberComparison + "\n\n");
               if (transactionRefNumberComparison != 0) {
                   comparison = transactionRefNumberComparison;
               }
           }
       }
    return comparison;
}

Question(s):

(1) Am I doing the right thing? When a comparison = 0, it returns as -2. Is this correct behavior because I always thought it to be between -1,0,1.

(2) Should I be using the comparator?

Happy programming...

PacificNW_Lover
  • 4,746
  • 31
  • 90
  • 144

4 Answers4

3

To address your specific questions:

  1. Yes, that looks fine. The result does not have to be -1, 0 or 1. Your code could be slightly less verbose, though, and just return as soon as it finds a result without using the comparison variable at all.
  2. If you're implementing Comparable, no need to deal with a Comparator. It's for when you need to compare something that isn't Comparable or need to compare in a different way.

Guava's ComparisonChain class makes a compareTo method like this incredibly easy:

public int compareTo(CreditCardTransactionDetail o) {
  return ComparisonChain.start()
      .compare(getDocumentNumber(), o.getDocumentNumber())
      .compare(getTransactionPostingDate(), o.getTransactionPostingDate())
      .compare(getTransactionDate(), o.getTransactionDate())
      .compare(getTransactionReferenceNumber(), o.getTransactionReferenceNumber())
      .result();
}
ColinD
  • 108,630
  • 30
  • 201
  • 202
2

Answer for (1): It's correct. see javadoc of Comparator.compare(T, T): "a negative integer, zero, or a positive integer as the first argument is less than, equal to, or greater than the second."

Or use Google Guava which encapsulates Comparator for easier and powerful usage:

  //Write 4 Comparators for each comparable field
 Ordering ordering = Ordering.from(comparatorDocumentNumber)
    .compound(comparatorTransactionPostingDate)
    .compound(comparatorTransactionDate)
    .compound(comparatorTransactionReferenceNumber);
 Collections.sort(list, ordering);

It decouples each Comparator, it's easy to change/ add/ remove fields order. EDIT: see ColinD's lighter solution.

卢声远 Shengyuan Lu
  • 31,208
  • 22
  • 85
  • 130
  • 1
    Writing 4 comparators seems wasteful unless you actually need to be able to compare all 4 different ways. If you do, then combining them with `compound` is nice... if not, `ComparisonChain` is really the best way to do this in Guava. – ColinD Apr 18 '11 at 04:15
0

Your compareTo is reasonable enough. compareTo can return values other than -1,0,1. Just negative, 0 and positive.

You should be using a comparator.

MeBigFatGuy
  • 28,272
  • 7
  • 61
  • 66
0
  1. According to the Comparable Documentation, compareTo():

    Returns a negative integer, zero, or a positive integer as this object 
    is less than, equal to, or greater than the specified object.
    

    So -2 is a valid result.

  2. That's a matter of preference, really. Personally I prefer using a Comparator, but compareTo() works just as well. In either case, your code would look pretty much the same.

aroth
  • 54,026
  • 20
  • 135
  • 176