PacificNW_Lover
PacificNW_Lover

Reputation: 5374

compareTo() and Collections.sort() Solution For Multiple Column Ordering (Ascending) question

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...

Upvotes: 2

Views: 6126

Answers (4)

卢声远 Shengyuan Lu
卢声远 Shengyuan Lu

Reputation: 32004

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.

Upvotes: 2

ColinD
ColinD

Reputation: 110054

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();
}

Upvotes: 3

aroth
aroth

Reputation: 54806

  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.

Upvotes: 0

MeBigFatGuy
MeBigFatGuy

Reputation: 28568

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.

Upvotes: 0

Related Questions